diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 681a0e726549..8081d8d99555 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4083,7 +4083,6 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD } - LightInstance *lights[RenderList::MAX_LIGHTS]; RenderList *render_list=NULL; @@ -4197,26 +4196,36 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD e->light_type=0x7F; //unshaded is zero } else { - //setup lights - uint16_t light_count=0; - uint16_t sort_key[4]; - uint8_t light_types[4]; + bool duplicate=false; - int dlc = MIN(directional_light_count,RenderList::MAX_LIGHTS);; - light_count=dlc; - for(int i=0;isort_key; - light_types[i]=VS::LIGHT_DIRECTIONAL; + for(int i=0;isort_key; + uint8_t light_type = VS::LIGHT_DIRECTIONAL; if (directional_lights[i]->base->shadow_enabled) { - light_types[i]|=0x8; + light_type|=0x8; if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) - light_types[i]|=0x10; + light_type|=0x10; else if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) - light_types[i]|=0x30; + light_type|=0x30; } + RenderList::Element *ec; + if (duplicate) { + + ec = render_list->add_element(); + memcpy(ec,e,sizeof(RenderList::Element)); + } else { + + ec=e; + duplicate=true; + } + + ec->light_type=light_type; + ec->light=sort_key; + ec->additive_ptr=&e->additive; + } @@ -4227,37 +4236,33 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD for(int i=0;i=RenderList::MAX_LIGHTS) - break; - LightInstance *li=light_instance_owner.get( liptr[i] ); if (!li || li->last_pass!=scene_pass) //lit by light not in visible scene continue; - light_types[light_count]=li->base->type; + uint8_t light_type=li->base->type; if (li->base->shadow_enabled) - light_types[light_count]|=0x8; - sort_key[light_count++]=li->sort_key; - - - } - - for(int i=0;isort_key; RenderList::Element *ec; - if (i>0) { + if (duplicate) { ec = render_list->add_element(); memcpy(ec,e,sizeof(RenderList::Element)); } else { + duplicate=true; ec=e; } - ec->light_type=light_types[i]; - ec->light=sort_key[i]; + ec->light_type=light_type; + ec->light=sort_key; ec->additive_ptr=&e->additive; + } + + } DEBUG_TEST_ERROR("Add Geometry"); @@ -5548,6 +5553,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans bool stores_glow = !shadow && (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) && !p_alpha_pass; + bool prev_blend=false; glDisable(GL_BLEND); for (int i=0;ielement_count;i++) { @@ -5620,6 +5626,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans additive=true; } + if (stores_glow) material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,!additive); @@ -5752,7 +5759,8 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (i==0 || light!=prev_light || rebind) { if (e->light!=0xFFFF) { - _setup_light(e->light&0x3); + _setup_light(e->light); + } } @@ -5824,6 +5832,9 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_uniform(MaterialShaderGLES2::WORLD_TRANSFORM, e->instance->transform); } + material_shader.set_uniform(MaterialShaderGLES2::NORMAL_MULT, e->mirror?-1.0:1.0); + + _render(e->geometry, material, skeleton,e->owner,e->instance->transform); DEBUG_TEST_ERROR("Rendering"); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 60a7731feac6..83365f2feb78 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -781,9 +781,22 @@ class RasterizerGLES2 : public Rasterizer { bool *additive_ptr; bool additive; bool mirror; - uint16_t light; - uint8_t light_type; - uint8_t sort_flags; + union { +#ifdef BIG_ENDIAN_ENABLED + struct { + uint8_t sort_flags; + uint8_t light_type; + uint16_t light; + }; +#else + struct { + uint16_t light; + uint8_t light_type; + uint8_t sort_flags; + }; +#endif + uint32_t sort_key; + }; }; @@ -896,27 +909,22 @@ class RasterizerGLES2 : public Rasterizer { _FORCE_INLINE_ bool operator()(const Element* A, const Element* B ) const { - if (A->sort_flags == B->sort_flags) { - if (A->light_type == B->light_type) { - if (A->material->shader_cache == B->material->shader_cache) { - if (A->material == B->material) { + if (A->sort_key == B->sort_key) { + if (A->material->shader_cache == B->material->shader_cache) { + if (A->material == B->material) { - return (A->geometry_cmp < B->geometry_cmp); - } else { - - return (A->material < B->material); - } + return (A->geometry_cmp < B->geometry_cmp); } else { - return (A->material->shader_cache < B->material->shader_cache); + return (A->material < B->material); } } else { - return A->light_type < B->light_type; + return (A->material->shader_cache < B->material->shader_cache); } } else { - return A->sort_flags < B->sort_flags; //one is null and one is not + return A->sort_key < B->sort_key; //one is null and one is not } } }; diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl index 602620a04bb2..b667e9176cb3 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -31,6 +31,8 @@ attribute vec4 color_attrib; // attrib:3 attribute vec2 uv_attrib; // attrib:4 attribute vec2 uv2_attrib; // attrib:5 +uniform float normal_mult; + #ifdef USE_SKELETON attribute vec4 bone_indices; // attrib:6 attribute vec4 bone_weights; // attrib:7 @@ -232,8 +234,10 @@ void main() { #endif highp vec4 vertex_in = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0); vec3 normal_in = normal_attrib; + normal_in*=normal_mult; #if defined(ENABLE_TANGENT_INTERP) vec3 tangent_in = tangent_attrib.xyz; + tangent_in*=normal_mult; #endif #ifdef USE_SKELETON diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 6fe8b8c4c2c6..c4879cf0652c 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -316,6 +316,9 @@ Map::Element *TileMap::_create_quadrant(const VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,friction); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); + if (is_inside_scene()) { xform = get_global_transform() * xform; RID space = get_world_2d()->get_space(); @@ -556,6 +559,38 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) { } } +void TileMap::set_collision_friction(float p_friction) { + + friction=p_friction; + for (Map::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_FRICTION,p_friction); + } + +} + +float TileMap::get_collision_friction() const{ + + return friction; +} + +void TileMap::set_collision_bounce(float p_bounce){ + + bounce=p_bounce; + for (Map::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_param(q.static_body,Physics2DServer::BODY_PARAM_BOUNCE,p_bounce); + } + +} +float TileMap::get_collision_bounce() const{ + + return bounce; +} + + uint32_t TileMap::get_collision_layer_mask() const { return collision_layer; @@ -584,6 +619,12 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); + ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); + + 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("get_cell","x","y"),&TileMap::get_cell); ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped); @@ -602,7 +643,9 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::INT,"quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_set",PROPERTY_HINT_RESOURCE_TYPE,"TileSet"),_SCS("set_tileset"),_SCS("get_tileset")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"collision_layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); ADD_SIGNAL(MethodInfo("settings_changed")); @@ -620,6 +663,8 @@ TileMap::TileMap() { center_x=false; center_y=false; collision_layer=1; + friction=1; + bounce=0; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 9265a7b55e1b..4b4d9489234c 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -98,6 +98,8 @@ class TileMap : public Node2D { Rect2 rect_cache; bool rect_cache_dirty; float fp_adjust; + float friction; + float bounce; uint32_t collision_layer; @@ -149,6 +151,12 @@ public: void set_collision_layer_mask(uint32_t p_layer); uint32_t get_collision_layer_mask() const; + void set_collision_friction(float p_friction); + float get_collision_friction() const; + + void set_collision_bounce(float p_bounce); + float get_collision_bounce() const; + void clear(); TileMap(); diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 2e03871063ab..ac2417d53912 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -276,6 +276,10 @@ bool BaseButton::is_pressed() const { return toggle_mode?status.pressed:status.press_attempt; } +bool BaseButton::is_hovered() const { + + return status.hovering; +} BaseButton::DrawMode BaseButton::get_draw_mode() const { @@ -337,6 +341,7 @@ void BaseButton::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&BaseButton::_input_event); ObjectTypeDB::bind_method(_MD("set_pressed","pressed"),&BaseButton::set_pressed); ObjectTypeDB::bind_method(_MD("is_pressed"),&BaseButton::is_pressed); + ObjectTypeDB::bind_method(_MD("is_hovered"),&BaseButton::is_hovered); ObjectTypeDB::bind_method(_MD("set_toggle_mode","enabled"),&BaseButton::set_toggle_mode); ObjectTypeDB::bind_method(_MD("is_toggle_mode"),&BaseButton::is_toggle_mode); ObjectTypeDB::bind_method(_MD("set_disabled","disabled"),&BaseButton::set_disabled); diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index 65563ddc03db..a2c640b9cfb1 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -83,6 +83,8 @@ public: bool is_pressed() const; ///< return wether button is pressed (toggled in) bool is_pressing() const; ///< return wether button is pressed (toggled in) + bool is_hovered() const; + void set_pressed(bool p_pressed); ///only works in toggle mode void set_toggle_mode(bool p_on); bool is_toggle_mode() const; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 4b4b4b3c737d..68787933608d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1002,7 +1002,7 @@ void Control::_window_input_event(InputEvent p_event) { } - p_event.mouse_button.global_x = pos.x; + p_event.mouse_button.global_x = pos.x; p_event.mouse_button.global_y = pos.y; pos = window->focus_inv_xform.xform(pos); diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index 8b9ea0b585ce..493644d2bc19 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -45,6 +45,7 @@ class SceneMainLoop; class Node; class Viewport; + class SceneMainLoop : public MainLoop { _THREAD_SAFE_CLASS_ diff --git a/tools/doc/doc_data.cpp b/tools/doc/doc_data.cpp index 35f114064476..319c1ad8b71c 100644 --- a/tools/doc/doc_data.cpp +++ b/tools/doc/doc_data.cpp @@ -34,6 +34,7 @@ #include "script_language.h" #include "io/marshalls.h" #include "io/compression.h" +#include "scene/resources/theme.h" void DocData::merge_from(const DocData& p_data) { @@ -111,6 +112,21 @@ void DocData::merge_from(const DocData& p_data) { } } + for(int i=0;i l; + Theme::get_default()->get_constant_list(cname,&l); + for (List::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="int"; + c.theme_properties.push_back(pd); + } + + l.clear(); + Theme::get_default()->get_color_list(cname,&l); + for (List::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="Color"; + c.theme_properties.push_back(pd); + } + + l.clear(); + Theme::get_default()->get_icon_list(cname,&l); + for (List::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="Texture"; + c.theme_properties.push_back(pd); + } + l.clear(); + Theme::get_default()->get_font_list(cname,&l); + for (List::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="Font"; + c.theme_properties.push_back(pd); + } + l.clear(); + Theme::get_default()->get_stylebox_list(cname,&l); + for (List::Element*E=l.front();E;E=E->next()) { + + PropertyDoc pd; + pd.name=E->get(); + pd.type="StyleBox"; + c.theme_properties.push_back(pd); + } + + } + + classes.pop_front(); } @@ -714,6 +784,35 @@ Error DocData::_load(Ref parser) { break; //end of } + } else if (name=="theme_items") { + + while(parser->read()==OK) { + + if (parser->get_node_type() == XMLParser::NODE_ELEMENT) { + + String name = parser->get_node_name(); + + if (name=="theme_item") { + + PropertyDoc prop; + + ERR_FAIL_COND_V(!parser->has_attribute("name"),ERR_FILE_CORRUPT); + prop.name=parser->get_attribute_value("name"); + ERR_FAIL_COND_V(!parser->has_attribute("type"),ERR_FILE_CORRUPT); + prop.type=parser->get_attribute_value("type"); + parser->read(); + if (parser->get_node_type()==XMLParser::NODE_TEXT) + prop.description=parser->get_node_data().strip_edges(); + c.theme_properties.push_back(prop); + } else { + ERR_EXPLAIN("Invalid tag in doc file: "+name); + ERR_FAIL_V(ERR_FILE_CORRUPT); + } + + } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name()=="members") + break; //end of + } + } else if (name=="constants") { while(parser->read()==OK) { @@ -897,7 +996,20 @@ Error DocData::save(const String& p_path) { } _write_string(f,1,""); - _write_string(f,0,""); + + _write_string(f,1,""); + if (c.theme_properties.size()) { + for(int i=0;i"); + _write_string(f,2,""); + + } + } + + _write_string(f,0,""); } diff --git a/tools/doc/doc_data.h b/tools/doc/doc_data.h index 59d6958aa5e7..018bd67aafcf 100644 --- a/tools/doc/doc_data.h +++ b/tools/doc/doc_data.h @@ -77,6 +77,7 @@ public: Vector signals; Vector constants; Vector properties; + Vector theme_properties; }; diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 0471d62d16a0..b7e708e360b1 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -168,6 +168,18 @@ void EditorHelpSearch::_update_search() { } } + for(int i=0;icreate_item(root); + item->set_metadata(0,"class_theme_item:"+E->key()+":"+c.theme_properties[i].name); + item->set_text(0,E->key()+"."+c.theme_properties[i].name+" (Theme Item)"); + item->set_icon(0,cicon); + } + } + + } //same but descriptions @@ -666,7 +678,48 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v } + if (cd.theme_properties.size()) { + + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color")); + class_desc->push_font(doc_title_font); + class_desc->add_text("GUI Theme Items:"); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + + class_desc->push_indent(1); + + //class_desc->add_newline(); + + for(int i=0;iget_line_count()-2; //gets overriden if description + class_desc->push_font(doc_code_font); + _add_type(cd.theme_properties[i].type); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/text_color")); + class_desc->add_text(" "+cd.theme_properties[i].name); + class_desc->pop(); + class_desc->pop(); + + if (cd.theme_properties[i].description!="") { + class_desc->push_font(doc_font); + class_desc->add_text(" "); + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/comment_color")); + class_desc->add_text(cd.theme_properties[i].description); + class_desc->pop(); + class_desc->pop(); + + } + + class_desc->add_newline(); + } + + class_desc->add_newline(); + class_desc->pop(); + + + } if (cd.signals.size()) { class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color")); @@ -905,6 +958,10 @@ void EditorHelp::_help_callback(const String& p_topic) { if (property_line.has(name)) line=property_line[name]; + } else if (what=="class_theme_item") { + + if (theme_property_line.has(name)) + line=theme_property_line[name]; } else if (what=="class_constant") { if (constant_line.has(name)) diff --git a/tools/editor/editor_help.h b/tools/editor/editor_help.h index 94a31ce90238..1c2b704b98c2 100644 --- a/tools/editor/editor_help.h +++ b/tools/editor/editor_help.h @@ -107,6 +107,7 @@ class EditorHelp : public VBoxContainer { Map method_line; Map signal_line; Map property_line; + Map theme_property_line; Map constant_line; int description_line;