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 2bea642583efeb68886e71950384f297f2d7ee12 Mon Sep 17 00:00:00 2001 From: reduz Date: Mon, 16 Feb 2015 14:45:11 -0300 Subject: -Some more work on 2D Lights (NOT FUNCTIONAL YET!) --- scene/2d/light_2d.cpp | 182 ++++++++++++++++++++++++++++++++ scene/2d/light_2d.h | 80 ++++++++++++++ scene/register_scene_types.cpp | 2 + servers/visual/rasterizer.h | 33 ++++++ servers/visual/visual_server_raster.cpp | 51 ++++++++- servers/visual/visual_server_raster.h | 2 + tools/editor/icons/icon_light_2d.png | Bin 0 -> 342 bytes 7 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 scene/2d/light_2d.cpp create mode 100644 scene/2d/light_2d.h create mode 100644 tools/editor/icons/icon_light_2d.png diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp new file mode 100644 index 0000000000..073e3a1645 --- /dev/null +++ b/scene/2d/light_2d.cpp @@ -0,0 +1,182 @@ +#include "light_2d.h" +#include "servers/visual_server.h" + +void Light2D::set_enabled( bool p_enabled) { + + VS::get_singleton()->canvas_light_set_enabled(canvas_light,p_enabled); + enabled=p_enabled; +} + +bool Light2D::is_enabled() const { + + return enabled; +} + +void Light2D::set_texture( const Ref& p_texture) { + + texture=p_texture; + if (texture.is_valid()) + VS::get_singleton()->canvas_light_set_texture(canvas_light,texture->get_rid()); + else + VS::get_singleton()->canvas_light_set_texture(canvas_light,RID()); +} + +Ref Light2D::get_texture() const { + + return texture; +} + +void Light2D::set_texture_offset( const Vector2& p_offset) { + + texture_offset=p_offset; + VS::get_singleton()->canvas_light_set_texture_offset(canvas_light,texture_offset); +} + +Vector2 Light2D::get_texture_offset() const { + + return texture_offset; +} + +void Light2D::set_color( const Color& p_color) { + + color=p_color; + VS::get_singleton()->canvas_light_set_color(canvas_light,color); + +} +Color Light2D::get_color() const { + + return color; +} + +void Light2D::set_height( float p_height) { + + height=p_height; + VS::get_singleton()->canvas_light_set_height(canvas_light,height); + +} +float Light2D::get_height() const { + + return height; +} + +void Light2D::set_z_range_min( int p_min_z) { + + z_min=p_min_z; + VS::get_singleton()->canvas_light_set_z_range(canvas_light,z_min,z_max); + +} +int Light2D::get_z_range_min() const { + + return z_min; +} + +void Light2D::set_z_range_max( int p_max_z) { + + z_max=p_max_z; + VS::get_singleton()->canvas_light_set_z_range(canvas_light,z_min,z_max); + +} +int Light2D::get_z_range_max() const { + + return z_max; +} + +void Light2D::set_item_mask( int p_mask) { + + item_mask=p_mask; + VS::get_singleton()->canvas_light_set_item_mask(canvas_light,item_mask); + +} + +int Light2D::get_item_mask() const { + + return item_mask; +} + +void Light2D::set_blend_mode( LightBlendMode p_blend_mode ) { + + blend_mode=p_blend_mode; + VS::get_singleton()->canvas_light_set_blend_mode(canvas_light,VS::CanvasLightBlendMode(blend_mode)); +} + +Light2D::LightBlendMode Light2D::get_blend_mode() const { + + return blend_mode; +} + +void Light2D::set_shadow_enabled( bool p_enabled) { + + shadow=p_enabled; + VS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light,shadow); + +} +bool Light2D::is_shadow_enabled() const { + + return shadow; +} + +void Light2D::_bind_methods() { + + + ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&Light2D::set_enabled); + ObjectTypeDB::bind_method(_MD("is_enabled"),&Light2D::is_enabled); + + ObjectTypeDB::bind_method(_MD("set_texture","texture"),&Light2D::set_texture); + ObjectTypeDB::bind_method(_MD("get_texture"),&Light2D::get_texture); + + ObjectTypeDB::bind_method(_MD("set_texture_offset","texture_offset"),&Light2D::set_texture_offset); + ObjectTypeDB::bind_method(_MD("get_texture_offset"),&Light2D::get_texture_offset); + + ObjectTypeDB::bind_method(_MD("set_color","color"),&Light2D::set_color); + ObjectTypeDB::bind_method(_MD("get_color"),&Light2D::get_color); + + ObjectTypeDB::bind_method(_MD("set_height","height"),&Light2D::set_height); + ObjectTypeDB::bind_method(_MD("get_height"),&Light2D::get_height); + + ObjectTypeDB::bind_method(_MD("set_z_range_min","z"),&Light2D::set_z_range_min); + ObjectTypeDB::bind_method(_MD("get_z_range_min"),&Light2D::get_z_range_min); + + ObjectTypeDB::bind_method(_MD("set_z_range_max","z"),&Light2D::set_z_range_max); + ObjectTypeDB::bind_method(_MD("get_z_range_max"),&Light2D::get_z_range_max); + + 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_blend_mode","blend_mode"),&Light2D::set_blend_mode); + ObjectTypeDB::bind_method(_MD("get_blend_mode"),&Light2D::get_blend_mode); + + ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled); + ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled); + + 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::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,"item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"blend_mode",PROPERTY_HINT_ENUM,"Add,Sub,Mul,Dodge,Burn,Lighten,Darken,Overlay,Screen"),_SCS("set_blend_mode"),_SCS("get_blend_mode")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow_enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled")); + + +} + +Light2D::Light2D() { + + canvas_light=VisualServer::get_singleton()->canvas_light_create(); + enabled=true; + shadow=false; + color=Color(1,1,1); + height=0; + z_min=-1024; + z_max=1024; + item_mask=1; + blend_mode=LIGHT_BLEND_ADD; + +} + +Light2D::~Light2D() { + + VisualServer::get_singleton()->free(canvas_light); +} diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h new file mode 100644 index 0000000000..ac8d587ea7 --- /dev/null +++ b/scene/2d/light_2d.h @@ -0,0 +1,80 @@ +#ifndef LIGHT_2D_H +#define LIGHT_2D_H + +#include "scene/2d/node_2d.h" + +class Light2D : public Node2D { + + OBJ_TYPE(Light2D,Node2D); +public: + + enum LightBlendMode { + LIGHT_BLEND_ADD, + LIGHT_BLEND_SUB, + LIGHT_BLEND_MULTIPLY, + LIGHT_BLEND_DODGE, + LIGHT_BLEND_BURN, + LIGHT_BLEND_LIGHTEN, + LIGHT_BLEND_DARKEN, + LIGHT_BLEND_OVERLAY, + LIGHT_BLEND_SCREEN, + }; + +private: + RID canvas_light; + bool enabled; + bool shadow; + Color color; + float height; + int z_min; + int z_max; + int item_mask; + LightBlendMode blend_mode; + Ref texture; + Vector2 texture_offset; + +protected: + + static void _bind_methods(); +public: + + + void set_enabled( bool p_enabled); + bool is_enabled() const; + + void set_texture( const Ref& p_texture); + Ref get_texture() const; + + void set_texture_offset( const Vector2& p_offset); + Vector2 get_texture_offset() const; + + void set_color( const Color& p_color); + Color get_color() const; + + void set_height( float p_height); + float get_height() const; + + void set_z_range_min( int p_min_z); + int get_z_range_min() const; + + void set_z_range_max( int p_max_z); + int get_z_range_max() const; + + void set_item_mask( int p_mask); + int get_item_mask() const; + + void set_blend_mode( LightBlendMode p_blend_mode ); + LightBlendMode get_blend_mode() const; + + void set_shadow_enabled( bool p_enabled); + bool is_shadow_enabled() const; + + + Light2D(); + ~Light2D(); +}; + + +VARIANT_ENUM_CAST(Light2D::LightBlendMode); + +#endif // LIGHT_2D_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 9600469e8a..89ce164ce9 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -79,6 +79,7 @@ #include "scene/resources/video_stream.h" #include "scene/2d/particles_2d.h" #include "scene/2d/path_2d.h" +#include "scene/2d/light_2d.h" #include "scene/2d/canvas_item.h" #include "scene/2d/sprite.h" @@ -472,6 +473,7 @@ void register_scene_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::set_type_enabled("CollisionShape2D",false); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 92c7b8ac14..63ebdbc34a 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -567,6 +567,39 @@ public: CANVAS_RECT_FLIP_V=8 }; + + struct CanvasLight { + + bool enabled; + bool shadow; + Color color; + Matrix32 xform; + float height; + int z_min; + int z_max; + int item_mask; + VS::CanvasLightBlendMode blend_mode; + RID texture; + void *texture_cache; // implementation dependent + Vector2 texture_offset; + + CanvasLight *next_ptr; + + CanvasLight() { + enabled=true; + shadow=false; + color=Color(1,1,1); + height=0; + z_min=-1024; + z_max=1024; + item_mask=1; + blend_mode=VS::CANVAS_LIGHT_BLEND_ADD; + texture_cache=NULL; + next_ptr=NULL; + } + }; + + struct CanvasItem { struct Command { diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index fc32702a12..e8fa319f11 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -3823,60 +3823,100 @@ void VisualServerRaster::canvas_item_raise(RID p_item) { RID VisualServerRaster::canvas_light_create() { - return RID(); + Rasterizer::CanvasLight *clight = memnew( Rasterizer::CanvasLight ); + return canvas_light_owner.make_rid(clight); } void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + } void VisualServerRaster::canvas_light_set_enabled(RID p_light, bool p_enabled){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->enabled=p_enabled; } void VisualServerRaster::canvas_light_set_transform(RID p_light, const Matrix32& p_transform){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->xform=p_transform; } void VisualServerRaster::canvas_light_set_texture(RID p_light, RID p_texture){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->texture=p_texture; } void VisualServerRaster::canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->texture_offset=p_offset; } void VisualServerRaster::canvas_light_set_color(RID p_light, const Color& p_color){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->color=p_color; + } void VisualServerRaster::canvas_light_set_height(RID p_light, float p_height){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->height=p_height; } void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->z_min=p_min_z; + clight->z_max=p_max_z; } void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->item_mask=p_mask; } void VisualServerRaster::canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->blend_mode=p_blend_mode; } void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->shadow=p_enabled; } 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); } void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){ + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); } @@ -4186,6 +4226,15 @@ void VisualServerRaster::free( RID p_rid ) { canvas_item_owner.free( p_rid ); memdelete( canvas_item ); + + } else if (canvas_light_owner.owns(p_rid)) { + + Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid); + ERR_FAIL_COND(!canvas_light); + + canvas_light_owner.free( p_rid ); + memdelete( canvas_light ); + } else if (scenario_owner.owns(p_rid)) { Scenario *scenario=scenario_owner.get(p_rid); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 57032ab441..c15b6ebb26 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -440,6 +440,8 @@ class VisualServerRaster : public VisualServer { }; + RID_Owner canvas_light_owner; + struct Viewport { diff --git a/tools/editor/icons/icon_light_2d.png b/tools/editor/icons/icon_light_2d.png new file mode 100644 index 0000000000..9162b33090 Binary files /dev/null and b/tools/editor/icons/icon_light_2d.png differ -- cgit v1.2.3 From ef565b977852bbcd4eb6fc5ed31087422fea632c Mon Sep 17 00:00:00 2001 From: greay Date: Tue, 17 Feb 2015 19:19:29 -0800 Subject: =?UTF-8?q?fix=20for=20=E2=80=9Cno=20viable=20conversion=20from=20?= =?UTF-8?q?'NSPoint'=20(aka=20'=5FNSPoint')=20to=20'CGPoint'=E2=80=9D=20bu?= =?UTF-8?q?ild=20error=20on=20OS=20X?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/osx/os_osx.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index af2552496b..1c0d1f9991 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1100,7 +1100,7 @@ void OS_OSX::warp_mouse_pos(const Point2& p_to) { NSPoint localPoint = { p_to.x, p_to.y }; NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil]; - NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(CGRect){.origin=pointInWindow}]; + NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(NSRect){.origin=pointInWindow}].origin; //point in scren coords CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y}; -- cgit v1.2.3 From 5ef3f7392faf0d2d9c136fc176f7a08cb774fe40 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 18 Feb 2015 19:39:44 -0300 Subject: support for light and normal mapping in 2D --- core/math/math_2d.h | 162 +++++++++- demos/2d/navpoly/navigation2.scn | Bin 0 -> 3564 bytes drivers/gles2/rasterizer_gles2.cpp | 531 +++++++++++++++++++++----------- drivers/gles2/rasterizer_gles2.h | 12 +- drivers/gles2/shader_compiler_gles2.cpp | 7 +- drivers/gles2/shaders/canvas.glsl | 62 +++- platform/winrt/os_winrt.cpp | 5 +- scene/2d/canvas_item.cpp | 15 + scene/2d/canvas_item.h | 6 +- scene/2d/canvas_modulate.cpp | 46 +++ scene/2d/canvas_modulate.h | 23 ++ scene/2d/light_2d.cpp | 103 ++++++- scene/2d/light_2d.h | 36 +-- scene/gui/popup_menu.h | 2 +- scene/register_scene_types.cpp | 2 + servers/visual/rasterizer.h | 29 +- servers/visual/visual_server_raster.cpp | 144 ++++++++- servers/visual/visual_server_raster.h | 28 +- servers/visual/visual_server_wrap_mt.h | 7 +- servers/visual_server.h | 18 +- 20 files changed, 952 insertions(+), 286 deletions(-) create mode 100644 demos/2d/navpoly/navigation2.scn create mode 100644 scene/2d/canvas_modulate.cpp create mode 100644 scene/2d/canvas_modulate.h diff --git a/core/math/math_2d.h b/core/math/math_2d.h index fa40d305f5..5bc1b5f0be 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -159,8 +159,8 @@ struct Vector2 { operator String() const { return String::num(x)+","+String::num(y); } - inline Vector2(float p_x,float p_y) { x=p_x; y=p_y; } - inline Vector2() { x=0; y=0; } + _FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; } + _FORCE_INLINE_ Vector2() { x=0; y=0; } }; _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2& p_vec) const { @@ -198,6 +198,8 @@ Vector2 Vector2::linear_interpolate(const Vector2& p_a, const Vector2& p_b,float typedef Vector2 Size2; typedef Vector2 Point2; +struct Matrix32; + struct Rect2 { @@ -224,6 +226,8 @@ struct Rect2 { return true; } + _FORCE_INLINE_ bool intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const; + bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const; inline bool encloses(const Rect2& p_rect) const { @@ -597,6 +601,160 @@ struct Matrix32 { }; +bool Rect2::intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const { + + //SAT intersection between local and transformed rect2 + + Vector2 xf_points[4]={ + p_xform.xform(p_rect.pos), + p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y)), + p_xform.xform(Vector2(p_rect.pos.x,p_rect.pos.y+p_rect.size.y)), + p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y+p_rect.size.y)), + }; + + real_t low_limit; + + //base rect2 first (faster) + + if (xf_points[0].y>pos.y) + goto next1; + if (xf_points[1].y>pos.y) + goto next1; + if (xf_points[2].y>pos.y) + goto next1; + if (xf_points[3].y>pos.y) + goto next1; + + return false; + + next1: + + low_limit=pos.y+size.y; + + if (xf_points[0].ypos.x) + goto next3; + if (xf_points[1].x>pos.x) + goto next3; + if (xf_points[2].x>pos.x) + goto next3; + if (xf_points[3].x>pos.x) + goto next3; + + return false; + + next3: + + low_limit=pos.x+size.x; + + if (xf_points[0].x maxb ) + return false; + if ( minb > maxa ) + return false; + + maxa=p_xform.elements[1].dot(xf_points2[0]); + mina=maxa; + + dp = p_xform.elements[1].dot(xf_points2[1]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + dp = p_xform.elements[1].dot(xf_points2[2]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + dp = p_xform.elements[1].dot(xf_points2[3]); + maxa=MAX(dp,maxa); + mina=MIN(dp,mina); + + maxb=p_xform.elements[1].dot(xf_points[0]); + minb=maxb; + + dp = p_xform.elements[1].dot(xf_points[1]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + dp = p_xform.elements[1].dot(xf_points[2]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + dp = p_xform.elements[1].dot(xf_points[3]); + maxb=MAX(dp,maxb); + minb=MIN(dp,minb); + + + if ( mina > maxb ) + return false; + if ( minb > maxa ) + return false; + + + return true; + +} Vector2 Matrix32::basis_xform(const Vector2& v) const { diff --git a/demos/2d/navpoly/navigation2.scn b/demos/2d/navpoly/navigation2.scn new file mode 100644 index 0000000000..224aed73f5 Binary files /dev/null and b/demos/2d/navpoly/navigation2.scn differ diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index d1e55f2488..382f4aa2e3 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -6409,7 +6409,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans } break; case VS::MATERIAL_BLEND_MODE_SUB: { - glBlendEquation(GL_FUNC_SUBTRACT); + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendFunc(GL_SRC_ALPHA,GL_ONE); } break; case VS::MATERIAL_BLEND_MODE_MUL: { @@ -7824,8 +7824,10 @@ void RasterizerGLES2::canvas_begin() { //material_shader.unbind(); canvas_shader.unbind(); canvas_shader.set_custom_shader(0); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,false); canvas_shader.bind(); canvas_shader.set_uniform(CanvasShaderGLES2::TEXTURE, 0); + canvas_use_modulate=false; _set_color_attrib(Color(1,1,1)); canvas_transform=Transform(); canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f); @@ -7840,7 +7842,6 @@ void RasterizerGLES2::canvas_begin() { canvas_opacity=1.0; canvas_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; - canvas_texscreen_used=false; uses_texpixel_size=false; canvas_last_shader=RID(); @@ -7876,7 +7877,7 @@ void RasterizerGLES2::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) { } break; case VS::MATERIAL_BLEND_MODE_SUB: { - glBlendEquation(GL_FUNC_SUBTRACT); + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendFunc(GL_SRC_ALPHA,GL_ONE); } break; case VS::MATERIAL_BLEND_MODE_MUL: { @@ -8325,13 +8326,265 @@ void RasterizerGLES2::canvas_set_transform(const Matrix32& p_transform) { //canvas_transform = Variant(p_transform); } +void RasterizerGLES2::_canvas_normal_set_flip(const Vector2& p_flip) { + + if (p_flip==normal_flip) + return; + normal_flip=p_flip; + canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP,normal_flip); +} + + +template +void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem *current_clip,bool &reclip) { + + int cc=p_item->commands.size(); + CanvasItem::Command **commands = p_item->commands.ptr(); + + + for(int i=0;itype) { + case CanvasItem::Command::TYPE_LINE: { + + CanvasItem::CommandLine* line = static_cast(c); + canvas_draw_line(line->from,line->to,line->color,line->width); + } break; + case CanvasItem::Command::TYPE_RECT: { + + CanvasItem::CommandRect* rect = static_cast(c); +// canvas_draw_rect(rect->rect,rect->region,rect->source,rect->flags&CanvasItem::CommandRect::FLAG_TILE,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V,rect->texture,rect->modulate); +#if 0 + int flags=0; + + if (rect->flags&CanvasItem::CommandRect::FLAG_REGION) { + flags|=Rasterizer::CANVAS_RECT_REGION; + } + if (rect->flags&CanvasItem::CommandRect::FLAG_TILE) { + flags|=Rasterizer::CANVAS_RECT_TILE; + } + if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H) { + + flags|=Rasterizer::CANVAS_RECT_FLIP_H; + } + if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V) { + + flags|=Rasterizer::CANVAS_RECT_FLIP_V; + } +#else + + int flags=rect->flags; +#endif + if (use_normalmap) + _canvas_normal_set_flip(Vector2((flags&CANVAS_RECT_FLIP_H)?-1:1,(flags&CANVAS_RECT_FLIP_V)?-1:1)); + canvas_draw_rect(rect->rect,flags,rect->source,rect->texture,rect->modulate); + + } break; + case CanvasItem::Command::TYPE_STYLE: { + + CanvasItem::CommandStyle* style = static_cast(c); + if (use_normalmap) + _canvas_normal_set_flip(Vector2(1,1)); + canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color); + + } break; + case CanvasItem::Command::TYPE_PRIMITIVE: { + + if (use_normalmap) + _canvas_normal_set_flip(Vector2(1,1)); + CanvasItem::CommandPrimitive* primitive = static_cast(c); + canvas_draw_primitive(primitive->points,primitive->colors,primitive->uvs,primitive->texture,primitive->width); + } break; + case CanvasItem::Command::TYPE_POLYGON: { + + if (use_normalmap) + _canvas_normal_set_flip(Vector2(1,1)); + CanvasItem::CommandPolygon* polygon = static_cast(c); + canvas_draw_polygon(polygon->count,polygon->indices.ptr(),polygon->points.ptr(),polygon->uvs.ptr(),polygon->colors.ptr(),polygon->texture,polygon->colors.size()==1); + + } break; + + case CanvasItem::Command::TYPE_POLYGON_PTR: { + + if (use_normalmap) + _canvas_normal_set_flip(Vector2(1,1)); + CanvasItem::CommandPolygonPtr* polygon = static_cast(c); + canvas_draw_polygon(polygon->count,polygon->indices,polygon->points,polygon->uvs,polygon->colors,polygon->texture,false); + } break; + case CanvasItem::Command::TYPE_CIRCLE: { + + CanvasItem::CommandCircle* circle = static_cast(c); + static const int numpoints=32; + Vector2 points[numpoints+1]; + points[numpoints]=circle->pos; + int indices[numpoints*3]; + + for(int i=0;ipos+Vector2( Math::sin(i*Math_PI*2.0/numpoints),Math::cos(i*Math_PI*2.0/numpoints) )*circle->radius; + indices[i*3+0]=i; + indices[i*3+1]=(i+1)%numpoints; + indices[i*3+2]=numpoints; + } + canvas_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true); + //canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1); + } break; + case CanvasItem::Command::TYPE_TRANSFORM: { + + CanvasItem::CommandTransform* transform = static_cast(c); + canvas_set_transform(transform->xform); + } break; + case CanvasItem::Command::TYPE_BLEND_MODE: { + + CanvasItem::CommandBlendMode* bm = static_cast(c); + canvas_set_blend_mode(bm->blend_mode); + + } break; + case CanvasItem::Command::TYPE_CLIP_IGNORE: { + + CanvasItem::CommandClipIgnore* ci = static_cast(c); + if (current_clip) { + + if (ci->ignore!=reclip) { + if (ci->ignore) { + + glDisable(GL_SCISSOR_TEST); + reclip=true; + } else { + + glEnable(GL_SCISSOR_TEST); + glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), + current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); + reclip=false; + } + } + } + + + + } break; + } + } + +} + +void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItem *shader_owner,Shader* shader) { + + if (canvas_shader.bind()) + rebind_texpixel_size=true; + + if (shader_owner->shader_version!=shader->version) { + //todo optimize uniforms + shader_owner->shader_version=shader->version; + } -void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { + if (shader->has_texscreen && framebuffer.active) { + + int x = viewport.x; + int y = window_size.height-(viewport.height+viewport.y); + + canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); + canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); + canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1); + glActiveTexture(GL_TEXTURE0+max_texture_units-1); + glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); + if (framebuffer.scale==1 && !canvas_texscreen_used) { +#ifdef GLEW_ENABLED + glReadBuffer(GL_COLOR_ATTACHMENT0); +#endif + glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); +// if (current_clip) { +// // print_line(" a clip "); +// } + + canvas_texscreen_used=true; + } + + glActiveTexture(GL_TEXTURE0); + + } + + if (shader->has_screen_uv) { + 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; + +} + +void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItem *shader_owner,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()); + + if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { + + RID rid; + if (F) { + rid=F->get(); + } + + if (!rid.is_valid()) { + + Map::Element *DT=shader->default_textures.find(E->key()); + if (DT) { + rid=DT->get(); + } + } + + if (rid.is_valid()) { + + int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic.. + + glActiveTexture(GL_TEXTURE0+tex_id); + Texture *t=texture_owner.get(rid); + if (!t) + glBindTexture(GL_TEXTURE_2D,white_tex); + else + glBindTexture(t->target,t->tex_id); + + glUniform1i(loc,tex_id); + tex_id++; + } + } else { + Variant &v=F?F->get():E->get().default_value; + canvas_shader.set_custom_uniform(idx,v); + } + + idx++; + } + + if (tex_id>1) { + glActiveTexture(GL_TEXTURE0); + } + +} + +void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) { CanvasItem *current_clip=NULL; Shader *shader_cache=NULL; + + bool rebind_shader=true; + canvas_opacity=1.0; + canvas_use_modulate=p_modulate!=Color(1,1,1,1); + canvas_modulate=p_modulate; + canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); + while(p_item_list) { CanvasItem *ci=p_item_list; @@ -8343,6 +8596,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { memdelete(ci->vp_render); ci->vp_render=NULL; canvas_last_shader=RID(); + 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; + + } if (current_clip!=ci->final_clip_owner) { @@ -8365,7 +8624,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { //begin rect CanvasItem *shader_owner = ci->shader_owner?ci->shader_owner:ci; - if (shader_owner->shader!=canvas_last_shader) { + if (shader_owner->shader!=canvas_last_shader || rebind_shader) { Shader *shader = NULL; if (shader_owner->shader.is_valid()) { @@ -8379,52 +8638,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { if (shader) { canvas_shader.set_custom_shader(shader->custom_code_id); - if (canvas_shader.bind()) - rebind_texpixel_size=true; - - if (shader_owner->shader_version!=shader->version) { - //todo optimize uniforms - shader_owner->shader_version=shader->version; - } - - if (shader->has_texscreen && framebuffer.active) { - - int x = viewport.x; - int y = window_size.height-(viewport.height+viewport.y); - - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1); - glActiveTexture(GL_TEXTURE0+max_texture_units-1); - glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); - if (framebuffer.scale==1 && !canvas_texscreen_used) { -#ifdef GLEW_ENABLED - glReadBuffer(GL_COLOR_ATTACHMENT0); -#endif - glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); - if (current_clip) { - // print_line(" a clip "); - } - - canvas_texscreen_used=true; - } - - glActiveTexture(GL_TEXTURE0); - - } - - if (shader->has_screen_uv) { - 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; - + _canvas_item_setup_shader_params(shader_owner,shader); } else { shader_cache=NULL; canvas_shader.set_custom_shader(0); @@ -8435,60 +8649,15 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { 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; + rebind_shader=false; } if (shader_cache) { - Shader *shader = shader_cache; - //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()); - - if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { - - RID rid; - if (F) { - rid=F->get(); - } - - if (!rid.is_valid()) { - - Map::Element *DT=shader->default_textures.find(E->key()); - if (DT) { - rid=DT->get(); - } - } - - if (rid.is_valid()) { - - int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic.. - - glActiveTexture(GL_TEXTURE0+tex_id); - Texture *t=texture_owner.get(rid); - if (!t) - glBindTexture(GL_TEXTURE_2D,white_tex); - else - glBindTexture(t->target,t->tex_id); - - glUniform1i(loc,tex_id); - tex_id++; - } - } else { - Variant &v=F?F->get():E->get().default_value; - canvas_shader.set_custom_uniform(idx,v); - } - - idx++; - } - - if (tex_id>1) { - glActiveTexture(GL_TEXTURE0); - } - + _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); } canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); @@ -8514,7 +8683,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { } break; case VS::MATERIAL_BLEND_MODE_SUB: { - glBlendEquation(GL_FUNC_SUBTRACT); + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); glBlendFunc(GL_SRC_ALPHA,GL_ONE); } break; case VS::MATERIAL_BLEND_MODE_MUL: { @@ -8531,128 +8700,114 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { canvas_blend_mode=ci->blend_mode; } - int cc=ci->commands.size(); - CanvasItem::Command **commands = ci->commands.ptr(); - canvas_opacity = ci->final_opacity; - for(int i=0;i(ci,current_clip,reclip); - CanvasItem::Command *c=commands[i]; + if (canvas_blend_mode==VS::MATERIAL_BLEND_MODE_MIX && p_light) { - switch(c->type) { - case CanvasItem::Command::TYPE_LINE: { + CanvasLight *light = p_light; + bool light_used=false; + bool subtract=false; - CanvasItem::CommandLine* line = static_cast(c); - canvas_draw_line(line->from,line->to,line->color,line->width); - } break; - case CanvasItem::Command::TYPE_RECT: { - CanvasItem::CommandRect* rect = static_cast(c); -// canvas_draw_rect(rect->rect,rect->region,rect->source,rect->flags&CanvasItem::CommandRect::FLAG_TILE,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V,rect->texture,rect->modulate); -#if 0 - int flags=0; + while(light) { - if (rect->flags&CanvasItem::CommandRect::FLAG_REGION) { - flags|=Rasterizer::CANVAS_RECT_REGION; - } - if (rect->flags&CanvasItem::CommandRect::FLAG_TILE) { - flags|=Rasterizer::CANVAS_RECT_TILE; - } - if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H) { + if (ci->light_mask&light->item_mask && p_z>=light->z_min && p_z<=light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache,light->rect_cache)) { - flags|=Rasterizer::CANVAS_RECT_FLIP_H; - } - if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V) { + //intersects this light - flags|=Rasterizer::CANVAS_RECT_FLIP_V; - } -#else + if (!light_used || subtract!=light->subtract) { - int flags=rect->flags; -#endif - canvas_draw_rect(rect->rect,flags,rect->source,rect->texture,rect->modulate); + subtract=light->subtract; - } break; - case CanvasItem::Command::TYPE_STYLE: { + if (subtract) { - CanvasItem::CommandStyle* style = static_cast(c); - canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color); + glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); - } break; - case CanvasItem::Command::TYPE_PRIMITIVE: { + } else { - CanvasItem::CommandPrimitive* primitive = static_cast(c); - canvas_draw_primitive(primitive->points,primitive->colors,primitive->uvs,primitive->texture,primitive->width); - } break; - case CanvasItem::Command::TYPE_POLYGON: { + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA,GL_ONE); - CanvasItem::CommandPolygon* polygon = static_cast(c); - canvas_draw_polygon(polygon->count,polygon->indices.ptr(),polygon->points.ptr(),polygon->uvs.ptr(),polygon->colors.ptr(),polygon->texture,polygon->colors.size()==1); + } + } - } break; + if (!light_used) { - case CanvasItem::Command::TYPE_POLYGON_PTR: { + canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING,true); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,false); + light_used=true; + normal_flip=Vector2(1,1); - CanvasItem::CommandPolygonPtr* polygon = static_cast(c); - canvas_draw_polygon(polygon->count,polygon->indices,polygon->points,polygon->uvs,polygon->colors,polygon->texture,false); - } break; - case CanvasItem::Command::TYPE_CIRCLE: { + } + bool light_rebind = canvas_shader.bind(); - CanvasItem::CommandCircle* circle = static_cast(c); - static const int numpoints=32; - Vector2 points[numpoints+1]; - points[numpoints]=circle->pos; - int indices[numpoints*3]; + 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); + } + + canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); + canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32()); + canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform); + if (canvas_use_modulate) + canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); + canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP,Vector2(1,1)); - for(int i=0;ipos+Vector2( Math::sin(i*Math_PI*2.0/numpoints),Math::cos(i*Math_PI*2.0/numpoints) )*circle->radius; - indices[i*3+0]=i; - indices[i*3+1]=(i+1)%numpoints; - indices[i*3+2]=numpoints; } - canvas_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true); - //canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1); - } break; - case CanvasItem::Command::TYPE_TRANSFORM: { - CanvasItem::CommandTransform* transform = static_cast(c); - canvas_set_transform(transform->xform); - } break; - case CanvasItem::Command::TYPE_BLEND_MODE: { + canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX,light->light_shader_xform); + 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); + 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); + if (!t) { + glBindTexture(GL_TEXTURE_2D,white_tex); + } else { - CanvasItem::CommandBlendMode* bm = static_cast(c); - canvas_set_blend_mode(bm->blend_mode); + glBindTexture(t->target,t->tex_id); + } - } break; - case CanvasItem::Command::TYPE_CLIP_IGNORE: { + glActiveTexture(GL_TEXTURE0); + _canvas_item_render_commands(ci,current_clip,reclip); //redraw using light - CanvasItem::CommandClipIgnore* ci = static_cast(c); - if (current_clip) { + } - if (ci->ignore!=reclip) { - if (ci->ignore) { + light=light->next_ptr; + } - glDisable(GL_SCISSOR_TEST); - reclip=true; - } else { + if (light_used) { - glEnable(GL_SCISSOR_TEST); - glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)), - current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height); - reclip=false; - } - } - } + canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING,false); + canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,canvas_use_modulate); + canvas_shader.bind(); - } break; + if (shader_owner && shader_cache) { + _canvas_item_setup_shader_params(shader_owner,shader_cache); + _canvas_item_setup_shader_uniforms(shader_owner,shader_cache); + } + + canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,ci->final_transform); + canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Matrix32()); + if (canvas_use_modulate) + canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE,canvas_modulate); + + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); } - } + } + if (reclip) { glEnable(GL_SCISSOR_TEST); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 508adf2859..f1ba04adc5 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1127,6 +1127,7 @@ class RasterizerGLES2 : public Rasterizer { bool active; int blur_size; + struct Blur { GLuint fbo; @@ -1186,11 +1187,15 @@ class RasterizerGLES2 : public Rasterizer { GLuint white_tex; RID canvas_tex; float canvas_opacity; + Color canvas_modulate; + bool canvas_use_modulate; bool uses_texpixel_size; bool rebind_texpixel_size; Transform canvas_transform; RID canvas_last_shader; bool canvas_texscreen_used; + Vector2 normal_flip; + _FORCE_INLINE_ void _canvas_normal_set_flip(const Vector2& p_flip); _FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture); @@ -1247,6 +1252,10 @@ class RasterizerGLES2 : public Rasterizer { GLuint tc0_id_cache; GLuint tc0_idx; + 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); public: /* TEXTURE API */ @@ -1562,7 +1571,8 @@ public: virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor); virtual void canvas_set_transform(const Matrix32& p_transform); - virtual void canvas_render_items(CanvasItem *p_item_list); + virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light); + /* ENVIRONMENT */ diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index d8841d407e..b2052c7cbb 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -261,6 +261,11 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a uses_light=true; } + if (vnode->name==vname_normal) { + uses_normal=true; + } + + } if (vnode->name==vname_time) { @@ -636,7 +641,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.uses_light=uses_light; r_flags.uses_time=uses_time; r_flags.uses_normalmap=uses_normalmap; - r_flags.uses_normal=uses_normalmap; + r_flags.uses_normal=uses_normal; r_flags.uses_texpixel_size=uses_texpixel_size; r_flags.uses_worldvec=uses_worldvec; r_code_line=code; diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index dc0af017d0..227a8b7bdd 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -26,7 +26,13 @@ uniform float time; #ifdef USE_LIGHTING uniform highp mat4 light_matrix; -varying vec4 light_tex_pos; +uniform vec2 light_pos; +varying vec4 light_uv_interp; + +#if defined(NORMAL_USED) +varying vec4 local_rot; +uniform vec2 normal_flip; +#endif #endif @@ -67,8 +73,13 @@ VERTEX_SHADER_CODE #ifdef USE_LIGHTING - light_tex_pos.xy = light_matrix * gl_Position; - light_tex_pos.zw=outvec.xy - light_matrix[4].xy; //likely wrong + light_uv_interp.xy = (light_matrix * outvec).xy; + light_uv_interp.zw = outvec.xy-light_pos; + +#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; + local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy )*normal_flip.y; +#endif #endif @@ -121,11 +132,22 @@ varying vec4 var2_interp; uniform float time; #endif +#ifdef USE_MODULATE + +uniform vec4 modulate; + +#endif #ifdef USE_LIGHTING uniform sampler2D light_texture; -varying vec4 light_tex_pos; +uniform vec4 light_color; +uniform float light_height; +varying vec4 light_uv_interp; + +#if defined(NORMAL_USED) +varying vec4 local_rot; +#endif #ifdef USE_SHADOWS @@ -151,6 +173,11 @@ 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) vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult; @@ -166,9 +193,13 @@ FRAGMENT_SHADER_CODE #ifdef USE_LIGHTING +#if defined(NORMAL_USED) + normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy; +#endif + float att=1.0; - vec3 light = texture2D(light_texture,light_tex_pos).rgb; + 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); @@ -183,18 +214,29 @@ FRAGMENT_SHADER_CODE #if defined(USE_LIGHT_SHADER_CODE) //light is written by the light shader { - vec2 light_dir = normalize(light_tex_pos.zw); - float light_distance = length(light_tex_pos.zw); + vec2 light_dir = normalize(light_uv_interp.zw); + float light_distance = length(light_uv_interp.zw); LIGHT_SHADER_CODE } + #else #if defined(NORMAL_USED) - vec2 light_normal = normalize(light_tex_pos.zw); - light = color.rgb * light * max(dot(light_normal,normal),0); + vec3 light_normal = normalize(vec3(light_uv_interp.zw,-light_height)); + light*=max(dot(-light_normal,normal),0); #endif - color.rgb=light; + color*=light; +/* +#ifdef USE_NORMAL + color.xy=local_rot.xy;//normal.xy; + color.zw=vec2(0.0,1.0); +#endif +*/ + 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 + } + //light shader code #endif diff --git a/platform/winrt/os_winrt.cpp b/platform/winrt/os_winrt.cpp index 89fa93c5c4..21a77b89cb 100644 --- a/platform/winrt/os_winrt.cpp +++ b/platform/winrt/os_winrt.cpp @@ -27,7 +27,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles1/rasterizer_gles1.h" #include "os_winrt.h" #include "drivers/nedmalloc/memory_pool_static_nedmalloc.h" #include "drivers/unix/memory_pool_static_malloc.h" @@ -62,11 +61,11 @@ using namespace Microsoft::WRL; int OSWinrt::get_video_driver_count() const { - return 2; + return 1; } const char * OSWinrt::get_video_driver_name(int p_driver) const { - return p_driver==0?"GLES2":"GLES1"; + return "GLES2"; } OS::VideoMode OSWinrt::get_default_video_mode() const { diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 44a7e25725..4021ba5910 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -458,6 +458,16 @@ CanvasItem::BlendMode CanvasItem::get_blend_mode() const { return blend_mode; } +void CanvasItem::set_light_mask(int p_light_mask) { + + light_mask=p_light_mask; + VS::get_singleton()->canvas_item_set_light_mask(canvas_item,p_light_mask); +} + +int CanvasItem::get_light_mask() const{ + + return light_mask; +} void CanvasItem::item_rect_changed() { @@ -857,6 +867,9 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&CanvasItem::set_blend_mode); ObjectTypeDB::bind_method(_MD("get_blend_mode"),&CanvasItem::get_blend_mode); + ObjectTypeDB::bind_method(_MD("set_light_mask","light_mask"),&CanvasItem::set_light_mask); + ObjectTypeDB::bind_method(_MD("get_light_mask"),&CanvasItem::get_light_mask); + ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&CanvasItem::set_opacity); ObjectTypeDB::bind_method(_MD("get_opacity"),&CanvasItem::get_opacity); ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity); @@ -912,6 +925,7 @@ void CanvasItem::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility 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") ); //exporting these two things doesn't really make much sense i think @@ -992,6 +1006,7 @@ CanvasItem::CanvasItem() : xform_change(this) { canvas_layer=NULL; use_parent_shader=false; global_invalid=true; + light_mask=1; C=NULL; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index e7260a6530..cccb63fe4c 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -71,6 +71,7 @@ private: List::Element *C; BlendMode blend_mode; + int light_mask; bool first_draw; bool hidden; @@ -80,8 +81,8 @@ private: bool drawing; bool block_transform_notify; bool behind; - bool use_parent_shader; + Ref shader; mutable Matrix32 global_transform; @@ -158,6 +159,9 @@ public: void set_blend_mode(BlendMode p_blend_mode); BlendMode get_blend_mode() const; + void set_light_mask(int p_light_mask); + int get_light_mask() const; + void set_opacity(float p_opacity); float get_opacity() const; diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp new file mode 100644 index 0000000000..82dd8012a5 --- /dev/null +++ b/scene/2d/canvas_modulate.cpp @@ -0,0 +1,46 @@ +#include "canvas_modulate.h" + + +void CanvasModulate::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_CANVAS) { + + VS::get_singleton()->canvas_set_modulate(get_canvas(),color); + } else if (p_what==NOTIFICATION_EXIT_CANVAS) { + + VS::get_singleton()->canvas_set_modulate(get_canvas(),Color(1,1,1,1)); + } +} + +void CanvasModulate::_bind_methods(){ + + ObjectTypeDB::bind_method(_MD("set_color","color"),&CanvasModulate::set_color); + ObjectTypeDB::bind_method(_MD("get_color"),&CanvasModulate::get_color); + + ADD_PROPERTY(PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color")); +} + + +void CanvasModulate::set_color(const Color& p_color){ + + color=p_color; + if (is_inside_tree()) { + VS::get_singleton()->canvas_set_modulate(get_canvas(),color); + } +} +Color CanvasModulate::get_color() const { + + return color; +} + + +CanvasModulate::CanvasModulate() +{ + color=Color(1,1,1,1); +} + +CanvasModulate::~CanvasModulate() +{ + +} + diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h new file mode 100644 index 0000000000..a6894f29c2 --- /dev/null +++ b/scene/2d/canvas_modulate.h @@ -0,0 +1,23 @@ +#ifndef CANVASMODULATE_H +#define CANVASMODULATE_H + +#include "scene/2d/node_2d.h" + +class CanvasModulate : public Node2D { + + OBJ_TYPE(CanvasModulate,Node2D); + + Color color; +protected: + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_color(const Color& p_color); + Color get_color() const; + + CanvasModulate(); + ~CanvasModulate(); +}; + +#endif // CANVASMODULATE_H diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 073e3a1645..cea8c06d3f 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -1,6 +1,39 @@ #include "light_2d.h" #include "servers/visual_server.h" +void Light2D::edit_set_pivot(const Point2& p_pivot) { + + set_texture_offset(p_pivot); + +} + +Point2 Light2D::edit_get_pivot() const { + + return get_texture_offset(); +} +bool Light2D::edit_has_pivot() const { + + return true; +} + +Rect2 Light2D::get_item_rect() const { + + if (texture.is_null()) + return Rect2(0,0,1,1); + + Size2i s; + + s = texture->get_size(); + Point2i ofs=texture_offset; + ofs-=s/2; + + if (s==Size2(0,0)) + s=Size2(1,1); + + return Rect2(ofs,s); +} + + void Light2D::set_enabled( bool p_enabled) { VS::get_singleton()->canvas_light_set_enabled(canvas_light,p_enabled); @@ -81,6 +114,28 @@ int Light2D::get_z_range_max() const { return z_max; } +void Light2D::set_layer_range_min( int p_min_layer) { + + layer_min=p_min_layer; + VS::get_singleton()->canvas_light_set_layer_range(canvas_light,layer_min,layer_max); + +} +int Light2D::get_layer_range_min() const { + + return layer_min; +} + +void Light2D::set_layer_range_max( int p_max_layer) { + + layer_max=p_max_layer; + VS::get_singleton()->canvas_light_set_layer_range(canvas_light,layer_min,layer_max); + +} +int Light2D::get_layer_range_max() const { + + return layer_max; +} + void Light2D::set_item_mask( int p_mask) { item_mask=p_mask; @@ -93,15 +148,15 @@ int Light2D::get_item_mask() const { return item_mask; } -void Light2D::set_blend_mode( LightBlendMode p_blend_mode ) { +void Light2D::set_subtract_mode( bool p_enable ) { - blend_mode=p_blend_mode; - VS::get_singleton()->canvas_light_set_blend_mode(canvas_light,VS::CanvasLightBlendMode(blend_mode)); + subtract_mode=p_enable; + VS::get_singleton()->canvas_light_set_subtract_mode(canvas_light,p_enable); } -Light2D::LightBlendMode Light2D::get_blend_mode() const { +bool Light2D::get_subtract_mode() const { - return blend_mode; + return subtract_mode; } void Light2D::set_shadow_enabled( bool p_enabled) { @@ -115,6 +170,25 @@ bool Light2D::is_shadow_enabled() const { return shadow; } +void Light2D::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + VS::get_singleton()->canvas_light_attach_to_canvas( canvas_light, get_canvas() ); + } + + if (p_what==NOTIFICATION_TRANSFORM_CHANGED) { + + VS::get_singleton()->canvas_light_set_transform( canvas_light, get_global_transform()); + } + + if (p_what==NOTIFICATION_EXIT_TREE) { + + VS::get_singleton()->canvas_light_attach_to_canvas( canvas_light, RID() ); + } + +} + void Light2D::_bind_methods() { @@ -139,11 +213,18 @@ void Light2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_z_range_max","z"),&Light2D::set_z_range_max); ObjectTypeDB::bind_method(_MD("get_z_range_max"),&Light2D::get_z_range_max); + ObjectTypeDB::bind_method(_MD("set_layer_range_min","layer"),&Light2D::set_layer_range_min); + ObjectTypeDB::bind_method(_MD("get_layer_range_min"),&Light2D::get_layer_range_min); + + ObjectTypeDB::bind_method(_MD("set_layer_range_max","layer"),&Light2D::set_layer_range_max); + ObjectTypeDB::bind_method(_MD("get_layer_range_max"),&Light2D::get_layer_range_max); + + 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_blend_mode","blend_mode"),&Light2D::set_blend_mode); - ObjectTypeDB::bind_method(_MD("get_blend_mode"),&Light2D::get_blend_mode); + ObjectTypeDB::bind_method(_MD("set_subtract_mode","enable"),&Light2D::set_subtract_mode); + ObjectTypeDB::bind_method(_MD("get_subtract_mode"),&Light2D::get_subtract_mode); ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled); ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled); @@ -155,8 +236,10 @@ void Light2D::_bind_methods() { 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::INT,"blend_mode",PROPERTY_HINT_ENUM,"Add,Sub,Mul,Dodge,Burn,Lighten,Darken,Overlay,Screen"),_SCS("set_blend_mode"),_SCS("get_blend_mode")); + 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")); @@ -171,8 +254,10 @@ Light2D::Light2D() { height=0; z_min=-1024; z_max=1024; + layer_min=0; + layer_max=0; item_mask=1; - blend_mode=LIGHT_BLEND_ADD; + subtract_mode=false; } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index ac8d587ea7..dbfd233d39 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -6,20 +6,6 @@ class Light2D : public Node2D { OBJ_TYPE(Light2D,Node2D); -public: - - enum LightBlendMode { - LIGHT_BLEND_ADD, - LIGHT_BLEND_SUB, - LIGHT_BLEND_MULTIPLY, - LIGHT_BLEND_DODGE, - LIGHT_BLEND_BURN, - LIGHT_BLEND_LIGHTEN, - LIGHT_BLEND_DARKEN, - LIGHT_BLEND_OVERLAY, - LIGHT_BLEND_SCREEN, - }; - private: RID canvas_light; bool enabled; @@ -28,17 +14,24 @@ private: float height; int z_min; int z_max; + int layer_min; + int layer_max; int item_mask; - LightBlendMode blend_mode; + bool subtract_mode; Ref texture; Vector2 texture_offset; protected: + void _notification(int p_what); static void _bind_methods(); public: + virtual void edit_set_pivot(const Point2& p_pivot); + virtual Point2 edit_get_pivot() const; + virtual bool edit_has_pivot() const; + void set_enabled( bool p_enabled); bool is_enabled() const; @@ -60,21 +53,26 @@ public: void set_z_range_max( int p_max_z); int get_z_range_max() const; + void set_layer_range_min( int p_min_layer); + int get_layer_range_min() const; + + void set_layer_range_max( int p_max_layer); + int get_layer_range_max() const; + void set_item_mask( int p_mask); int get_item_mask() const; - void set_blend_mode( LightBlendMode p_blend_mode ); - LightBlendMode get_blend_mode() const; + void set_subtract_mode( bool p_enable ); + bool get_subtract_mode() const; void set_shadow_enabled( bool p_enabled); bool is_shadow_enabled() const; + virtual Rect2 get_item_rect() const; Light2D(); ~Light2D(); }; -VARIANT_ENUM_CAST(Light2D::LightBlendMode); - #endif // LIGHT_2D_H diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index c2e988de95..d825ea2b68 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -90,7 +90,7 @@ public: void add_icon_check_item(const Ref& p_icon,const String& p_label,int p_ID=-1,uint32_t p_accel=0); void add_check_item(const String& p_label,int p_ID=-1,uint32_t p_accel=0); void add_submenu_item(const String& p_label,const String& p_submenu, int p_ID=-1); - + void set_item_text(int p_idx,const String& p_text); void set_item_icon(int p_idx,const Ref& p_icon); void set_item_checked(int p_idx,bool p_checked); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 89ce164ce9..ff525203bf 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -104,6 +104,7 @@ #include "scene/2d/remote_transform_2d.h" #include "scene/2d/y_sort.h" #include "scene/2d/navigation2d.h" +#include "scene/2d/canvas_modulate.h" #include "scene/2d/position_2d.h" #include "scene/2d/tile_map.h" @@ -264,6 +265,7 @@ void register_scene_types() { ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); /* REGISTER GUI */ diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 63ebdbc34a..2ae283f3b7 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -570,6 +570,7 @@ public: struct CanvasLight { + bool enabled; bool shadow; Color color; @@ -577,12 +578,23 @@ public: float height; int z_min; int z_max; + int layer_min; + int layer_max; int item_mask; - VS::CanvasLightBlendMode blend_mode; + bool subtract; RID texture; - void *texture_cache; // implementation dependent Vector2 texture_offset; + RID canvas; + + + void *texture_cache; // implementation dependent + Rect2 rect_cache; + Matrix32 xform_cache; + + Matrix32 light_shader_xform; + Vector2 light_shader_pos; + CanvasLight *filter_next_ptr; CanvasLight *next_ptr; CanvasLight() { @@ -592,10 +604,13 @@ public: height=0; z_min=-1024; z_max=1024; + layer_min=0; + layer_max=0; item_mask=1; - blend_mode=VS::CANVAS_LIGHT_BLEND_ADD; + subtract=false; texture_cache=NULL; next_ptr=NULL; + filter_next_ptr=NULL; } }; @@ -722,6 +737,7 @@ public: bool visible; bool ontop; VS::MaterialBlendMode blend_mode; + int light_mask; Vector commands; mutable bool custom_rect; mutable bool rect_dirty; @@ -739,8 +755,9 @@ public: CanvasItem* shader_owner; ViewportRender *vp_render; - const Rect2& get_rect() const { + Rect2 global_rect_cache; + const Rect2& get_rect() const { if (custom_rect || !rect_dirty) return rect; @@ -864,7 +881,7 @@ public: } void clear() { for (int i=0;ichild_items[idx].mirror; } +void VisualServerRaster::canvas_set_modulate(RID p_canvas,const Color& p_color) { + + Canvas * canvas = canvas_owner.get(p_canvas); + ERR_FAIL_COND(!canvas); + canvas->modulate=p_color; +} + + RID VisualServerRaster::canvas_item_create() { @@ -3305,14 +3314,27 @@ bool VisualServerRaster::canvas_item_is_visible(RID p_item) const { } +void VisualServerRaster::canvas_item_set_light_mask(RID p_canvas_item,int p_mask) { + + VS_CHANGED; + + CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); + ERR_FAIL_COND(!canvas_item); + + if (canvas_item->light_mask==p_mask) + return; + VS_CHANGED; + + canvas_item->light_mask=p_mask; + +} + + void VisualServerRaster::canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - if (!canvas_item) { - printf("!canvas_item\n"); - }; ERR_FAIL_COND(!canvas_item); if (canvas_item->blend_mode==p_blend) @@ -3832,6 +3854,23 @@ void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas) Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + if (clight->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(clight->canvas); + canvas->lights.erase(clight); + } + + if (!canvas_owner.owns(p_canvas)) + p_canvas=RID(); + clight->canvas=p_canvas; + + if (clight->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(clight->canvas); + canvas->lights.insert(clight); + } + + } void VisualServerRaster::canvas_light_set_enabled(RID p_light, bool p_enabled){ @@ -3885,6 +3924,16 @@ void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p clight->z_max=p_max_z; } + +void VisualServerRaster::canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer) { + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->layer_min=p_min_layer; + clight->layer_max=p_max_layer; + +} + void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); @@ -3893,11 +3942,12 @@ void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ } -void VisualServerRaster::canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode){ +void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) { + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - clight->blend_mode=p_blend_mode; + clight->subtract=p_enable; } void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){ @@ -4194,7 +4244,13 @@ void VisualServerRaster::free( RID p_rid ) { canvas->child_items[i].item->parent=RID(); } - + + for (Set::Element *E=canvas->lights.front();E;E=E->next()) { + + E->get()->canvas=RID(); + } + + canvas_owner.free( p_rid ); memdelete( canvas ); @@ -4232,6 +4288,12 @@ void VisualServerRaster::free( RID p_rid ) { Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid); ERR_FAIL_COND(!canvas_light); + if (canvas_light->canvas.is_valid()) { + Canvas* canvas = canvas_owner.get(canvas_light->canvas); + if (canvas) + canvas->lights.erase(canvas_light); + } + canvas_light_owner.free( p_rid ); memdelete( canvas_light ); @@ -6280,7 +6342,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S } -void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) { +void VisualServerRaster::_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) { static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1; @@ -6298,7 +6360,7 @@ void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,cons for(int i=0;icanvas_render_items(z_list[i]); + rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_modulate,p_lights); } } @@ -6404,7 +6466,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat //something to draw? ci->final_transform=xform; ci->final_opacity=opacity * ci->self_opacity; - + ci->global_rect_cache=global_rect; int zidx = p_z-CANVAS_ITEM_Z_MIN; @@ -6417,6 +6479,8 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat z_last_list[zidx]=ci; } + + ci->next=NULL; } @@ -6430,7 +6494,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat } -void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform) { +void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights) { rasterizer->canvas_begin(); @@ -6463,30 +6527,30 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans for(int i=0;icanvas_render_items(z_list[i]); + rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_canvas->modulate,p_lights); } } else { for(int i=0;ichild_items[i]; - _render_canvas_item_tree(ci.item,p_transform,clip_rect); + _render_canvas_item_tree(ci.item,p_transform,clip_rect,p_canvas->modulate,p_lights); //mirroring (useful for scrolling backgrounds) if (ci.mirror.x!=0) { Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0)); - _render_canvas_item_tree(ci.item,xform2,clip_rect); + _render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights); } if (ci.mirror.y!=0) { Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y)); - _render_canvas_item_tree(ci.item,xform2,clip_rect); + _render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights); } if (ci.mirror.y!=0 && ci.mirror.x!=0) { Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror); - _render_canvas_item_tree(ci.item,xform2,clip_rect); + _render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights); } } @@ -6549,7 +6613,43 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Map canvas_map; + Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height); + Rasterizer::CanvasLight *lights=NULL; + for (Map::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { + + Matrix32 xf = p_viewport->global_transform * E->get().transform; + + //find lights in canvas + + + for(Set::Element *F=E->get().canvas->lights.front();F;F=F->next()) { + + Rasterizer::CanvasLight* cl=F->get(); + if (cl->enabled && cl->texture.is_valid()) { + //not super efficient.. + Size2 tsize(rasterizer->texture_get_width(cl->texture),rasterizer->texture_get_height(cl->texture)); + Vector2 offset=tsize/2.0; + 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; + cl->texture_cache=NULL; + Matrix32 scale; + scale.scale(cl->rect_cache.size); + 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]; + } + + + + + } + } + canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); } @@ -6560,7 +6660,19 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ // print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size())); //print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform); Matrix32 xform = p_viewport->global_transform * E->get()->transform; - _render_canvas( E->get()->canvas,xform ); + + Rasterizer::CanvasLight *canvas_lights=NULL; + + Rasterizer::CanvasLight *ptr=lights; + while(ptr) { + if (E->get()->layer>=ptr->layer_min && E->get()->layer<=ptr->layer_max) { + ptr->next_ptr=canvas_lights; + canvas_lights=ptr; + } + ptr=ptr->filter_next_ptr; + } + + _render_canvas( E->get()->canvas,xform,canvas_lights ); i++; } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index c15b6ebb26..eec677068e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -410,6 +410,8 @@ class VisualServerRaster : public VisualServer { } }; + struct CanvasLight; + struct Canvas { Set viewports; @@ -419,8 +421,10 @@ class VisualServerRaster : public VisualServer { CanvasItem *item; }; + Set lights; Vector child_items; + Color modulate; int find_item(CanvasItem *p_item) { for(int i=0;i _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); @@ -1075,6 +1079,8 @@ public: virtual RID canvas_create(); virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring); virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const; + virtual void canvas_set_modulate(RID p_canvas,const Color& p_color); + virtual RID canvas_item_create(); @@ -1085,6 +1091,8 @@ public: virtual bool canvas_item_is_visible(RID p_item) const; virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend); + virtual void canvas_item_set_light_mask(RID p_canvas_item,int p_mask); + //virtual void canvas_item_set_rect(RID p_item, const Rect2& p_rect); @@ -1137,20 +1145,10 @@ public: virtual void canvas_light_set_color(RID p_light, const Color& p_color); virtual void canvas_light_set_height(RID p_light, float p_height); 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); - enum CanvasightBlendMode { - CANVAS_LIGHT_BLEND_ADD, - CANVAS_LIGHT_BLEND_SUB, - CANVAS_LIGHT_BLEND_MULTIPLY, - CANVAS_LIGHT_BLEND_DODGE, - CANVAS_LIGHT_BLEND_BURN, - CANVAS_LIGHT_BLEND_LIGHTEN, - CANVAS_LIGHT_BLEND_DARKEN, - CANVAS_LIGHT_BLEND_OVERLAY, - CANVAS_LIGHT_BLEND_SCREEN, - }; - virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode); + 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); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 9574dff018..c94425c586 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1087,6 +1087,8 @@ public: FUNC0R(RID,canvas_create); FUNC3(canvas_set_item_mirroring,RID,RID,const Point2&); FUNC2RC(Point2,canvas_get_item_mirroring,RID,RID); + FUNC2(canvas_set_modulate,RID,const Color&); + FUNC0R(RID,canvas_item_create); @@ -1097,7 +1099,7 @@ public: FUNC1RC(bool,canvas_item_is_visible,RID); FUNC2(canvas_item_set_blend_mode,RID,MaterialBlendMode ); - + FUNC2(canvas_item_set_light_mask,RID,int ); //FUNC(canvas_item_set_rect,RID, const Rect2& p_rect); FUNC2(canvas_item_set_transform,RID, const Matrix32& ); @@ -1155,10 +1157,11 @@ public: FUNC2(canvas_light_set_texture_offset,RID,const Vector2&); FUNC2(canvas_light_set_color,RID,const Color&); FUNC2(canvas_light_set_height,RID,float); + 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_blend_mode,RID,CanvasLightBlendMode); + 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); diff --git a/servers/visual_server.h b/servers/visual_server.h index 49ae8ce4e6..e9bc97628f 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -944,6 +944,8 @@ public: virtual RID canvas_create()=0; virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring)=0; virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const=0; + virtual void canvas_set_modulate(RID p_canvas,const Color& p_color)=0; + virtual RID canvas_item_create()=0; @@ -953,6 +955,8 @@ public: virtual void canvas_item_set_visible(RID p_item,bool p_visible)=0; virtual bool canvas_item_is_visible(RID p_item) const=0; + virtual void canvas_item_set_light_mask(RID p_item,int p_mask)=0; + virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend)=0; virtual void canvas_item_attach_viewport(RID p_item, RID p_viewport)=0; @@ -1008,20 +1012,10 @@ public: virtual void canvas_light_set_color(RID p_light, const Color& p_color)=0; virtual void canvas_light_set_height(RID p_light, float p_height)=0; 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; - enum CanvasLightBlendMode { - CANVAS_LIGHT_BLEND_ADD, - CANVAS_LIGHT_BLEND_SUB, - CANVAS_LIGHT_BLEND_MULTIPLY, - CANVAS_LIGHT_BLEND_DODGE, - CANVAS_LIGHT_BLEND_BURN, - CANVAS_LIGHT_BLEND_LIGHTEN, - CANVAS_LIGHT_BLEND_DARKEN, - CANVAS_LIGHT_BLEND_OVERLAY, - CANVAS_LIGHT_BLEND_SCREEN, - }; - virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode)=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; 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; -- cgit v1.2.3 From cf75bf842ddda61d82bf492938a7b0849d2be718 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 19 Feb 2015 00:27:02 -0300 Subject: -improved pathfinding accuracy (i hope?) --- scene/2d/navigation2d.cpp | 39 ++++++++++++++++++++++++++++++++++++++- scene/2d/navigation2d.h | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp index 5e93dac61d..46af68444a 100644 --- a/scene/2d/navigation2d.cpp +++ b/scene/2d/navigation2d.cpp @@ -1,5 +1,7 @@ #include "navigation2d.h" +#define USE_ENTRY_POINT + void Navigation2D::_navpoly_link(int p_id) { ERR_FAIL_COND(!navpoly_map.has(p_id)); @@ -336,12 +338,25 @@ Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vect List open_list; + begin_poly->entry=p_start; + for(int i=0;iedges.size();i++) { if (begin_poly->edges[i].C) { begin_poly->edges[i].C->prev_edge=begin_poly->edges[i].C_edge; +#ifdef USE_ENTRY_POINT + Vector2 edge[2]={ + _get_vertex(begin_poly->edges[i].point), + _get_vertex(begin_poly->edges[(i+1)%begin_poly->edges.size()].point) + }; + + Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry,edge); + begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry); + begin_poly->edges[i].C->entry=entry; +#else begin_poly->edges[i].C->distance=begin_poly->center.distance_to(begin_poly->edges[i].C->center); +#endif open_list.push_back(begin_poly->edges[i].C); if (begin_poly->edges[i].C==end_poly) { @@ -381,8 +396,9 @@ Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vect Polygon *p=least_cost_poly->get(); //open the neighbours for search + int es = p->edges.size(); - for(int i=0;iedges.size();i++) { + for(int i=0;iedges[i]; @@ -390,8 +406,22 @@ Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vect if (!e.C) continue; +#ifdef USE_ENTRY_POINT + Vector2 edge[2]={ + _get_vertex(p->edges[i].point), + _get_vertex(p->edges[(i+1)%es].point) + }; + + Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry,edge); + float distance = p->entry.distance_to(edge_entry) + p->distance; + +#else + float distance = p->center.distance_to(e.C->center) + p->distance; +#endif + + if (e.C->prev_edge!=-1) { //oh this was visited already, can we win the cost? @@ -399,12 +429,19 @@ Vector Navigation2D::get_simple_path(const Vector2& p_start, const Vect e.C->prev_edge=e.C_edge; e.C->distance=distance; +#ifdef USE_ENTRY_POINT + e.C->entry=edge_entry; +#endif } } else { //add to open neighbours e.C->prev_edge=e.C_edge; e.C->distance=distance; +#ifdef USE_ENTRY_POINT + e.C->entry=edge_entry; +#endif + open_list.push_back(e.C); if (e.C==end_poly) { diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h index 1fca80dc5c..7ff01bb442 100644 --- a/scene/2d/navigation2d.h +++ b/scene/2d/navigation2d.h @@ -55,6 +55,7 @@ class Navigation2D : public Node2D { Vector edges; Vector2 center; + Vector2 entry; float distance; int prev_edge; -- cgit v1.2.3 From 3fdf3d8eabf3ca8c756de52a4bb6aa302c1f454f Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 19 Feb 2015 11:54:03 -0300 Subject: -fix compilation of godot server --- servers/visual/rasterizer_dummy.cpp | 2 +- servers/visual/rasterizer_dummy.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 6c1b6697c1..7fb8eb02fc 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1622,7 +1622,7 @@ void RasterizerDummy::canvas_set_transform(const Matrix32& p_transform) { } -void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list) { +void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) { } diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index c72149f88f..baa48951d6 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -710,7 +710,7 @@ public: virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor); virtual void canvas_set_transform(const Matrix32& p_transform); - virtual void canvas_render_items(CanvasItem *p_item_list); + virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light); /* ENVIRONMENT */ -- cgit v1.2.3 From c6a87d3a50582d294e0c468795145899213c8a8e Mon Sep 17 00:00:00 2001 From: Nathan Warden Date: Thu, 19 Feb 2015 11:15:13 -0500 Subject: Changed the tooltip message for instancing a scene. - Old wording was misleading as it gave the impression that you could select any node from another scene. - New wording matches the functionality that you instance the entire scene as a single node. --- tools/editor/scene_tree_dock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 6f33d4b3d1..2012d96664 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1254,7 +1254,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec tb = memnew( ToolButton ); tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_INSTANCE, false)); - tb->set_tooltip("Instance a Node from scene file."); + tb->set_tooltip("Instance a scene file as a Node."); hbc_top->add_child(tb); tool_buttons[TOOL_INSTANCE]=tb; -- cgit v1.2.3 From daeac73c543d4abfa49399a3abb03da42d77684d Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 19 Feb 2015 18:12:45 -0300 Subject: restored @ for nodepaths/stringnames --- modules/gdscript/gd_tokenizer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index 6f968f2080..1979577a17 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -538,9 +538,12 @@ 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; -- 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