diff --git a/demos/3d/fixed_materials/fixed_materials.scn b/demos/3d/fixed_materials/fixed_materials.scn index 210d4208ee82..de14ccdb154e 100644 Binary files a/demos/3d/fixed_materials/fixed_materials.scn and b/demos/3d/fixed_materials/fixed_materials.scn differ diff --git a/demos/3d/platformer/stage.xml b/demos/3d/platformer/stage.xml index 1dc7d1e7ab21..fbb720c006ea 100644 --- a/demos/3d/platformer/stage.xml +++ b/demos/3d/platformer/stage.xml @@ -6,14 +6,19 @@ + False 4 0, 0, 0, 1 1 1 + 0.6 True 2 + 1.3 + 1.2 + 1 0 0.5 False @@ -150,8 +155,12 @@ False "zoom" 1 + "use_snap" + False "ofs" 1, 1 + "snap" + 10 "3D" @@ -165,15 +174,15 @@ "distance" 6.622579 "x_rot" - 1.570796 + 0.358295 "y_rot" - 0 + 0.45 "use_orthogonal" False "use_environment" False "pos" - 8.30511, 0.427271, 15.7846 + 9.41795, 2.98588, 13.6496 "distance" diff --git a/demos/3d/platformer/tiles.res b/demos/3d/platformer/tiles.res index 9270f4c49121..0ab7c92ef667 100644 Binary files a/demos/3d/platformer/tiles.res and b/demos/3d/platformer/tiles.res differ diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index 60c88af508f3..9e13f12abef7 100644 --- a/drivers/gles1/rasterizer_gles1.cpp +++ b/drivers/gles1/rasterizer_gles1.cpp @@ -2165,6 +2165,74 @@ int RasterizerGLES1::multimesh_get_visible_instances(RID p_multimesh) const { } +/* IMMEDIATE API */ + + +RID RasterizerGLES1::immediate_create() { + + Immediate *im = memnew( Immediate ); + return immediate_owner.make_rid(im); + +} + +void RasterizerGLES1::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture){ + + +} +void RasterizerGLES1::immediate_vertex(RID p_immediate,const Vector3& p_vertex){ + + +} +void RasterizerGLES1::immediate_normal(RID p_immediate,const Vector3& p_normal){ + + +} +void RasterizerGLES1::immediate_tangent(RID p_immediate,const Plane& p_tangent){ + + +} +void RasterizerGLES1::immediate_color(RID p_immediate,const Color& p_color){ + + +} +void RasterizerGLES1::immediate_uv(RID p_immediate,const Vector2& tex_uv){ + + +} +void RasterizerGLES1::immediate_uv2(RID p_immediate,const Vector2& tex_uv){ + + +} + +void RasterizerGLES1::immediate_end(RID p_immediate){ + + +} +void RasterizerGLES1::immediate_clear(RID p_immediate) { + + +} + +AABB RasterizerGLES1::immediate_get_aabb(RID p_immediate) const { + + return AABB(Vector3(-1,-1,-1),Vector3(2,2,2)); +} + +void RasterizerGLES1::immediate_set_material(RID p_immediate,RID p_material) { + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + im->material=p_material; +} + +RID RasterizerGLES1::immediate_get_material(RID p_immediate) const { + + const Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND_V(!im,RID()); + return im->material; + +} + /* PARTICLES API */ @@ -5327,6 +5395,12 @@ bool RasterizerGLES1::is_mesh(const RID& p_rid) const { return mesh_owner.owns(p_rid); } + +bool RasterizerGLES1::is_immediate(const RID& p_rid) const { + + return immediate_owner.owns(p_rid); +} + bool RasterizerGLES1::is_multimesh(const RID& p_rid) const { return multimesh_owner.owns(p_rid); @@ -5447,6 +5521,13 @@ void RasterizerGLES1::free(const RID& p_rid) { particles_owner.free(p_rid); memdelete(particles); + } else if (immediate_owner.owns(p_rid)) { + + Immediate *immediate = immediate_owner.get(p_rid); + ERR_FAIL_COND(!immediate); + + immediate_owner.free(p_rid); + memdelete(immediate); } else if (particles_instance_owner.owns(p_rid)) { ParticlesInstance *particles_isntance = particles_instance_owner.get(p_rid); diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h index dbb411c8a309..323d00a46766 100644 --- a/drivers/gles1/rasterizer_gles1.h +++ b/drivers/gles1/rasterizer_gles1.h @@ -371,6 +371,15 @@ class RasterizerGLES1 : public Rasterizer { mutable RID_Owner multimesh_owner; + + struct Immediate { + + RID material; + int empty; + }; + + mutable RID_Owner immediate_owner; + struct Particles : public Geometry { ParticleSystemSW data; // software particle system @@ -963,6 +972,23 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; + /* IMMEDIATE API */ + + virtual RID immediate_create(); + virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID()); + virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex); + virtual void immediate_normal(RID p_immediate,const Vector3& p_normal); + virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent); + virtual void immediate_color(RID p_immediate,const Color& p_color); + virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv); + virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv); + virtual void immediate_end(RID p_immediate); + virtual void immediate_clear(RID p_immediate); + virtual AABB immediate_get_aabb(RID p_immediate) const; + virtual void immediate_set_material(RID p_immediate,RID p_material); + virtual RID immediate_get_material(RID p_immediate) const; + + /* PARTICLES API */ virtual RID particles_create(); @@ -1120,6 +1146,7 @@ public: virtual void add_mesh( const RID& p_mesh, const InstanceData *p_data); virtual void add_multimesh( const RID& p_multimesh, const InstanceData *p_data); + virtual void add_immediate( const RID& p_immediate, const InstanceData *p_data) {} virtual void add_particles( const RID& p_particle_instance, const InstanceData *p_data); virtual void end_scene(); @@ -1176,6 +1203,7 @@ public: virtual bool is_material(const RID& p_rid) const; virtual bool is_mesh(const RID& p_rid) const; virtual bool is_multimesh(const RID& p_rid) const; + virtual bool is_immediate(const RID& p_rid) const; virtual bool is_particles(const RID &p_beam) const; virtual bool is_light(const RID& p_rid) const; diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 472e92f23a0c..74a82e1a5ca9 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -2489,6 +2489,156 @@ int RasterizerGLES2::multimesh_get_visible_instances(RID p_multimesh) const { } +/* IMMEDIATE API */ + + +RID RasterizerGLES2::immediate_create() { + + Immediate *im = memnew( Immediate ); + return immediate_owner.make_rid(im); + +} + +void RasterizerGLES2::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(im->building); + + Immediate::Chunk ic; + ic.texture=p_texture; + ic.primitive=p_rimitive; + im->chunks.push_back(ic); + im->mask=0; + im->building=true; + + +} +void RasterizerGLES2::immediate_vertex(RID p_immediate,const Vector3& p_vertex){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + Immediate::Chunk *c = &im->chunks.back()->get(); + + + if (c->vertices.empty() && im->chunks.size()==1) { + + im->aabb.pos=p_vertex; + im->aabb.size=Vector3(); + } else { + im->aabb.expand_to(p_vertex); + } + + if (im->mask&VS::ARRAY_FORMAT_NORMAL) + c->normals.push_back(chunk_normal); + if (im->mask&VS::ARRAY_FORMAT_TANGENT) + c->tangents.push_back(chunk_tangent); + if (im->mask&VS::ARRAY_FORMAT_COLOR) + c->colors.push_back(chunk_color); + if (im->mask&VS::ARRAY_FORMAT_TEX_UV) + c->uvs.push_back(chunk_uv); + if (im->mask&VS::ARRAY_FORMAT_TEX_UV2) + c->uvs2.push_back(chunk_uv2); + im->mask|=VS::ARRAY_FORMAT_VERTEX; + c->vertices.push_back(p_vertex); + +} + + +void RasterizerGLES2::immediate_normal(RID p_immediate,const Vector3& p_normal){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + im->mask|=VS::ARRAY_FORMAT_NORMAL; + chunk_normal=p_normal; + +} +void RasterizerGLES2::immediate_tangent(RID p_immediate,const Plane& p_tangent){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + im->mask|=VS::ARRAY_FORMAT_TANGENT; + chunk_tangent=p_tangent; + +} +void RasterizerGLES2::immediate_color(RID p_immediate,const Color& p_color){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + im->mask|=VS::ARRAY_FORMAT_COLOR; + chunk_color=p_color; + +} +void RasterizerGLES2::immediate_uv(RID p_immediate,const Vector2& tex_uv){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + im->mask|=VS::ARRAY_FORMAT_TEX_UV; + chunk_uv=tex_uv; + +} +void RasterizerGLES2::immediate_uv2(RID p_immediate,const Vector2& tex_uv){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + im->mask|=VS::ARRAY_FORMAT_TEX_UV2; + chunk_uv2=tex_uv; + +} + +void RasterizerGLES2::immediate_end(RID p_immediate){ + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(!im->building); + + im->building=false; + +} +void RasterizerGLES2::immediate_clear(RID p_immediate) { + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + ERR_FAIL_COND(im->building); + + im->chunks.clear(); +} + +AABB RasterizerGLES2::immediate_get_aabb(RID p_immediate) const { + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND_V(!im,AABB()); + return im->aabb; +} + +void RasterizerGLES2::immediate_set_material(RID p_immediate,RID p_material) { + + Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!im); + im->material=p_material; + +} + +RID RasterizerGLES2::immediate_get_material(RID p_immediate) const { + + const Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND_V(!im,RID()); + return im->material; + +} + /* PARTICLES API */ @@ -3793,9 +3943,16 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { //print_line("UCF: "+itos(p_shader->uniforms.size())); + int first_tex_index=0xFFFFF; + p_shader->first_texture=StringName(); + for(Map::Element *E=p_shader->uniforms.front();E;E=E->next()) { uniform_names.push_back("_"+String(E->key())); + if (E->get().type==ShaderLanguage::TYPE_TEXTURE && E->get().orderfirst_texture=E->key(); + first_tex_index=E->get().order; + } } if (p_shader->mode==VS::SHADER_MATERIAL) { @@ -3819,6 +3976,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { if (flags.uses_screen_uv) { enablers.push_back("#define ENABLE_SCREEN_UV\n"); } + if (flags.uses_discard) { + enablers.push_back("#define ENABLE_DISCARD\n"); + } material_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names,enablers); } else { @@ -3827,6 +3987,8 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { p_shader->valid=true; p_shader->has_alpha=flags.uses_alpha || flags.uses_texscreen; + p_shader->writes_vertex=flags.vertex_code_writes_vertex; + p_shader->uses_discard=flags.uses_discard; p_shader->has_texscreen=flags.uses_texscreen; p_shader->has_screen_uv=flags.uses_screen_uv; p_shader->can_zpass=!flags.uses_discard && !flags.vertex_code_writes_vertex; @@ -3887,16 +4049,19 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD RenderList *render_list=NULL; - bool has_alpha = m->blend_mode!=VS::MATERIAL_BLEND_MODE_MIX || (m->shader_cache && m->shader_cache->has_alpha) || m->flags[VS::MATERIAL_FLAG_ONTOP]; + bool has_base_alpha=(m->shader_cache && m->shader_cache->has_alpha); + bool has_blend_alpha=m->blend_mode!=VS::MATERIAL_BLEND_MODE_MIX || m->flags[VS::MATERIAL_FLAG_ONTOP]; + bool has_alpha = has_base_alpha || has_blend_alpha; if (shadow) { - if (has_alpha) + if (has_blend_alpha || (has_base_alpha && !m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS])) return; //bye - if (true) { - m = shadow_mat_ptr; //for now do this always + if (m->shader_cache && !m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && !m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]) { + //shader does not use discard and does not write a vertex position, use generic material + m = shadow_mat_ptr; if (m->last_pass!=frame) { if (m->shader.is_valid()) { @@ -3939,6 +4104,9 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD RenderList::Element *e = render_list->add_element(); + if (!e) + return; + e->geometry=p_geometry; e->geometry_cmp=p_geometry_cmp; e->material=m; @@ -3974,6 +4142,18 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD e->light_type=0xFF; // no lights! e->light=0xFFFF; + if (!shadow && !has_blend_alpha && has_alpha && m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]) { + + //if nothing exists, add this element as opaque too + RenderList::Element *oe = opaque_render_list.add_element(); + + if (!oe) + return; + + memcpy(oe,e,sizeof(RenderList::Element)); + oe->additive_ptr=&oe->additive; + } + if (shadow || m->flags[VS::MATERIAL_FLAG_UNSHADED]) { e->light_type=0x7F; //unshaded is zero @@ -4098,6 +4278,17 @@ void RasterizerGLES2::add_multimesh( const RID& p_multimesh, const InstanceData } +void RasterizerGLES2::add_immediate( const RID& p_immediate, const InstanceData *p_data) { + + + Immediate *immediate = immediate_owner.get(p_immediate); + ERR_FAIL_COND(!immediate); + + _add_geometry(immediate,p_data,immediate,NULL); + +} + + void RasterizerGLES2::add_particles( const RID& p_particle_instance, const InstanceData *p_data){ //print_line("adding particles"); @@ -4169,7 +4360,7 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ } -bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material *p_material,bool p_no_const_light) { +bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material *p_material,bool p_no_const_light,bool p_opaque_pass) { if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED]) { glDisable(GL_CULL_FACE); @@ -4196,11 +4387,19 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ,shadow_filter>SHADOW_FILTER_PCF5); //material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,true); + if (p_opaque_pass && p_material->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS] && p_material->shader_cache && p_material->shader_cache->has_alpha) { + + material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA,true); + } else { + material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA,false); + + } + if (!shadow) { bool depth_test=!p_material->flags[VS::MATERIAL_FLAG_ONTOP]; - bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW]; + bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW] && (p_opaque_pass || !p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]); if (current_depth_mask!=depth_write) { current_depth_mask=depth_write; @@ -4276,6 +4475,10 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material if (t) { if (t->render_target) t->render_target->last_pass=frame; + if (E->key()==p_material->shader_cache->first_texture) { + tc0_idx=texcoord; + tc0_id_cache=t->tex_id; + } glBindTexture(t->target,t->tex_id); } else glBindTexture(GL_TEXTURE_2D,white_tex); //no texture @@ -5019,6 +5222,109 @@ void RasterizerGLES2::_render(const Geometry *p_geometry,const Material *p_mater }; } } break; + case Geometry::GEOMETRY_IMMEDIATE: { + + bool restore_tex=false; + const Immediate *im = static_cast( p_geometry ); + if (im->building) { + return; + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + for(const List::Element *E=im->chunks.front();E;E=E->next()) { + + const Immediate::Chunk &c=E->get(); + if (c.vertices.empty()) { + continue; + } + for(int i=0;itarget,t->tex_id); + restore_tex=true; + + + } else if (restore_tex) { + + glActiveTexture(GL_TEXTURE0+tc0_idx); + glBindTexture(GL_TEXTURE_2D,tc0_id_cache); + restore_tex=false; + } + + if (!c.normals.empty()) { + + glEnableVertexAttribArray(VS::ARRAY_NORMAL); + glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false,sizeof(Vector3),c.normals.ptr()); + + } else { + + glDisableVertexAttribArray(VS::ARRAY_NORMAL); + } + + if (!c.tangents.empty()) { + + glEnableVertexAttribArray(VS::ARRAY_TANGENT); + glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false,sizeof(Plane),c.tangents.ptr()); + + } else { + + glDisableVertexAttribArray(VS::ARRAY_TANGENT); + } + + if (!c.colors.empty()) { + + glEnableVertexAttribArray(VS::ARRAY_COLOR); + glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false,sizeof(Color),c.colors.ptr()); + + } else { + + glDisableVertexAttribArray(VS::ARRAY_COLOR); + _set_color_attrib(Color(1, 1, 1,1)); + } + + + if (!c.uvs.empty()) { + + glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false,sizeof(Vector2),c.uvs.ptr()); + + } else { + + glDisableVertexAttribArray(VS::ARRAY_TEX_UV); + } + + if (!c.uvs2.empty()) { + + glEnableVertexAttribArray(VS::ARRAY_TEX_UV2); + glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, false,sizeof(Vector2),c.uvs2.ptr()); + + } else { + + glDisableVertexAttribArray(VS::ARRAY_TEX_UV2); + } + + + glEnableVertexAttribArray(VS::ARRAY_VERTEX); + glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false,sizeof(Vector3),c.vertices.ptr()); + glDrawArrays(gl_primitive[c.primitive],0,c.vertices.size()); + + + } + + + if (restore_tex) { + + glActiveTexture(GL_TEXTURE0+tc0_idx); + glBindTexture(GL_TEXTURE_2D,tc0_id_cache); + restore_tex=false; + } + + + } break; case Geometry::GEOMETRY_PARTICLES: { @@ -5275,8 +5581,10 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (desired_blend) { glEnable(GL_BLEND); + glColorMask(1,1,1,0); } else { glDisable(GL_BLEND); + glColorMask(1,1,1,1); } prev_blend=desired_blend; @@ -5337,7 +5645,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (material!=prev_material || rebind) { - rebind = _setup_material(e->geometry,material,additive); + rebind = _setup_material(e->geometry,material,additive,!p_alpha_pass); DEBUG_TEST_ERROR("Setup material"); _rinfo.mat_change_count++; @@ -5530,9 +5838,12 @@ void RasterizerGLES2::_process_glow_bloom() { _copy_screen_quad(); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_COPY,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES]; Vector2 psize(1.0/framebuffer.blur_size,1.0/framebuffer.blur_size); + float pscale = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_SCALE]; + float pmag = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH]; + for(int i=0;ibg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) { @@ -5705,6 +6022,7 @@ void RasterizerGLES2::_draw_tex_bg() { if (current_env->fx_enabled[VS::ENV_FX_HDR]) nrg*=0.25; //go down a quarter for hdr copy_shader.set_uniform(CopyShaderGLES2::ENERGY,nrg); + copy_shader.set_uniform(CopyShaderGLES2::CUSTOM_ALPHA,float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW])); Vector3 vertices[4]={ Vector3(-1,-1,1), @@ -5774,6 +6092,7 @@ void RasterizerGLES2::_draw_tex_bg() { copy_shader.set_conditional(CopyShaderGLES2::USE_ENERGY,false); copy_shader.set_conditional(CopyShaderGLES2::USE_RGBE,false); copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA,false); } void RasterizerGLES2::end_scene() { @@ -5854,7 +6173,7 @@ void RasterizerGLES2::end_scene() { bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR]; else bgcolor = Globals::get_singleton()->get("render/default_clear_color"); - float a = use_fb ? 0.0 : 1.0; + float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0; glClearColor(bgcolor.r,bgcolor.g,bgcolor.b,a); _glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); @@ -5923,7 +6242,7 @@ void RasterizerGLES2::end_scene() { } alpha_render_list.sort_z(); - _render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,false,true); + _render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true); glColorMask(1,1,1,1); // material_shader.set_conditional( MaterialShaderGLES2::USE_FOG,false); @@ -5953,7 +6272,12 @@ void RasterizerGLES2::end_scene() { _process_hdr(); } if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) { - _process_glow_bloom(); + _process_glow_bloom(); + int glow_transfer_mode=current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE]; + if (glow_transfer_mode==1) + copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,true); + if (glow_transfer_mode==2) + copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,true); } glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer); @@ -6024,6 +6348,8 @@ void RasterizerGLES2::end_scene() { copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,false); copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,false); material_shader.set_conditional(MaterialShaderGLES2::USE_HDR,false); @@ -6216,8 +6542,8 @@ void RasterizerGLES2::end_shadow_map() { //glDisable(GL_POLYGON_OFFSET_FILL); - if (!use_rgba_shadowmaps) - glColorMask(1, 1, 1, 1); + //if (!use_rgba_shadowmaps) + glColorMask(1, 1, 1, 1); DEBUG_TEST_ERROR("Drawing Shadow"); shadow=NULL; @@ -6950,6 +7276,10 @@ bool RasterizerGLES2::is_mesh(const RID& p_rid) const { return mesh_owner.owns(p_rid); } +bool RasterizerGLES2::is_immediate(const RID& p_rid) const { + + return immediate_owner.owns(p_rid); +} bool RasterizerGLES2::is_multimesh(const RID& p_rid) const { return multimesh_owner.owns(p_rid); @@ -7074,6 +7404,13 @@ void RasterizerGLES2::free(const RID& p_rid) { multimesh_owner.free(p_rid); memdelete(multimesh); + } else if (immediate_owner.owns(p_rid)) { + + Immediate *immediate = immediate_owner.get(p_rid); + ERR_FAIL_COND(!immediate); + + immediate_owner.free(p_rid); + memdelete(immediate); } else if (particles_owner.owns(p_rid)) { Particles *particles = particles_owner.get(p_rid); @@ -8121,6 +8458,8 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo draw_next_frame=false; use_framebuffers=true; framebuffer.active=false; + tc0_id_cache=0; + tc0_idx=0; }; RasterizerGLES2::~RasterizerGLES2() { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 673297dd5127..0fee8bf91830 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -173,8 +173,11 @@ class RasterizerGLES2 : public Rasterizer { bool can_zpass; bool has_texscreen; bool has_screen_uv; + bool writes_vertex; + bool uses_discard; Map uniforms; + StringName first_texture; SelfList dirty_list; @@ -190,6 +193,8 @@ class RasterizerGLES2 : public Rasterizer { can_zpass=true; has_texscreen=false; has_screen_uv=false; + writes_vertex=false; + uses_discard=false; } @@ -235,6 +240,7 @@ class RasterizerGLES2 : public Rasterizer { flags[VS::MATERIAL_FLAG_VISIBLE]=true; for(int i=0;i multimesh_owner; mutable SelfList::List _multimesh_dirty_list; + struct Immediate : public Geometry { + + struct Chunk { + + RID texture; + VS::PrimitiveType primitive; + Vector vertices; + Vector normals; + Vector tangents; + Vector colors; + Vector uvs; + Vector uvs2; + }; + + List chunks; + bool building; + int mask; + AABB aabb; + + Immediate() { type=GEOMETRY_IMMEDIATE; building=false;} + + }; + + mutable RID_Owner immediate_owner; + struct Particles : public Geometry { ParticleSystemSW data; // software particle system @@ -585,11 +616,15 @@ class RasterizerGLES2 : public Rasterizer { bg_param[VS::ENV_BG_PARAM_CUBEMAP]=RID(); bg_param[VS::ENV_BG_PARAM_ENERGY]=1.0; bg_param[VS::ENV_BG_PARAM_SCALE]=1.0; + bg_param[VS::ENV_BG_PARAM_GLOW]=0.0; for(int i=0;iname==vname_vertex && p_assign_left) { + vertex_code_writes_vertex=true; + } + } if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) { if (vnode->name==vname_discard) { @@ -644,5 +650,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { vname_binormal_interp="BINORMAL"; vname_var1_interp="VAR1"; vname_var2_interp="VAR2"; + vname_vertex="VERTEX"; } diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index 2f4aa7647ee6..d683f5b4f301 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -61,6 +61,7 @@ private: StringName vname_binormal_interp; StringName vname_var1_interp; StringName vname_var2_interp; + StringName vname_vertex; Map *uniforms; diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index d665fddd2c00..bcd3e6ad4b91 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -315,6 +315,7 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() { for(int i=0;icustom_defines.size();i++) { strings.push_back(cc->custom_defines[i]); + DEBUG_PRINT("CD #"+itos(i)+": "+String(cc->custom_defines[i])); } } @@ -349,9 +350,11 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() { strings.push_back(vertex_code2.get_data()); #ifdef DEBUG_SHADER + + DEBUG_PRINT("\nVertex Code:\n\n"+String(code_string.get_data())); for(int i=0;i 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r))); + color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g))); + color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b))); + } + +#endif + +#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT) color.rgb+=glow.rgb; #endif @@ -316,6 +335,9 @@ void main() { color.a=1.0; #endif +#ifdef USE_CUSTOM_ALPHA + color.a=custom_alpha; +#endif gl_FragColor = color; } diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl index 1794f18801d0..a919e3b1e29a 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -386,6 +386,7 @@ VERTEX_SHADER_CODE specular_interp=vec3(0.0); } } + #else #ifdef SHADELESS @@ -722,21 +723,28 @@ void main() { -#ifdef FRAGMENT_SHADER_CODE_USE_DISCARD - float discard_=0.0; +#if defined(ENABLE_DISCARD) + bool discard_=false; #endif FRAGMENT_SHADER_CODE -#ifdef FRAGMENT_SHADER_CODE_USE_DISCARD - if (discard_>0.0) { +#if defined(ENABLE_DISCARD) + if (discard_) { //easy to eliminate dead code discard; } #endif +#ifdef ENABLE_CLIP_ALPHA + if (diffuse.a<0.99) { + //used for doublepass and shadowmapping + discard; + } +#endif + float shadow_attenuation = 1.0; @@ -902,7 +910,10 @@ FRAGMENT_SHADER_CODE # if !defined(LIGHT_TYPE_DIRECTIONAL) && !defined(LIGHT_TYPE_OMNI) && !defined (LIGHT_TYPE_SPOT) //none +#ifndef SHADELESS diffuse.rgb=vec3(0.0,0.0,0.0); +#endif + # endif diffuse.rgb+=const_light_mult*emission; @@ -959,6 +970,7 @@ FRAGMENT_SHADER_CODE #ifdef USE_HDR diffuse.rgb*=0.25; #endif + gl_FragColor = diffuse; #endif } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 3b6a62898e32..d1ee7087e7d6 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -189,6 +189,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int orientation; String release_keystore; + String release_password; String release_username; struct APKExportData { @@ -241,11 +242,11 @@ public: virtual int get_device_count() const; virtual String get_device_name(int p_device) const; virtual String get_device_info(int p_device) const; - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return !p_debug; } virtual String get_binary_extension() const { return "apk"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -285,6 +286,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant& release_keystore=p_value; else if (n=="keystore/release_user") release_username=p_value; + else if (n=="keystore/release_password") + release_password=p_value; else if (n=="apk_expansion/enable") apk_expansion=p_value; else if (n=="apk_expansion/SALT") @@ -343,6 +346,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret) r_ret=release_keystore; else if (n=="keystore/release_user") r_ret=release_username; + else if (n=="keystore/release_password") + r_ret=release_password; else if (n=="apk_expansion/enable") r_ret=apk_expansion; else if (n=="apk_expansion/SALT") @@ -968,7 +973,7 @@ Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata,const String& -Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_apk; @@ -1088,34 +1093,51 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_de ep.step("Adding Files..",1); - Error err=OK; Vector cl = cmdline.strip_edges().split(" "); - if (apk_expansion) { - String apkfname="main."+itos(version_code)+"."+package+".obb"; - String fullpath=p_path.get_base_dir().plus_file(apkfname); - FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE); - if (!pf) { - EditorNode::add_io_error("Could not write expansion package file: "+apkfname); - return OK; + if (p_dumb) { + + String host = EditorSettings::get_singleton()->get("file_server/host"); + int port = EditorSettings::get_singleton()->get("file_server/post"); + String passwd = EditorSettings::get_singleton()->get("file_server/password"); + cl.push_back("-rfs"); + cl.push_back(host+":"+itos(port)); + if (passwd!="") { + cl.push_back("-rfs_pass"); + cl.push_back(passwd); } - err = save_pack(pf); - memdelete(pf); - cl.push_back("-main_pack"); - cl.push_back(apkfname); - cl.push_back("-main_pack_md5"); - cl.push_back(FileAccess::get_md5(fullpath)); - cl.push_back("-main_pack_cfg"); - cl.push_back(apk_expansion_salt+","+apk_expansion_pkey); + } else { + //all files - APKExportData ed; - ed.ep=&ep; - ed.apk=apk; + if (apk_expansion) { - err = export_project_files(save_apk_file,&ed,false); + String apkfname="main."+itos(version_code)+"."+package+".obb"; + String fullpath=p_path.get_base_dir().plus_file(apkfname); + FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE); + if (!pf) { + EditorNode::add_io_error("Could not write expansion package file: "+apkfname); + return OK; + } + err = save_pack(pf); + memdelete(pf); + cl.push_back("-main_pack"); + cl.push_back(apkfname); + cl.push_back("-main_pack_md5"); + cl.push_back(FileAccess::get_md5(fullpath)); + cl.push_back("-main_pack_cfg"); + cl.push_back(apk_expansion_salt+","+apk_expansion_pkey); + + } else { + + APKExportData ed; + ed.ep=&ep; + ed.apk=apk; + + err = export_project_files(save_apk_file,&ed,false); + } } if (cl.size()) { @@ -1179,7 +1201,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_de } else { keystore=release_keystore; - password=p_password; + password=release_password; user=release_username; ep.step("Signing Release APK..",103); @@ -1388,7 +1410,7 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) { } -Error EditorExportPlatformAndroid::run(int p_device) { +Error EditorExportPlatformAndroid::run(int p_device, bool p_dumb) { ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER); device_lock->lock(); @@ -1407,7 +1429,7 @@ Error EditorExportPlatformAndroid::run(int p_device) { ep.step("Exporting APK",0); String export_to=EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpexport.apk"; - Error err = export_project(export_to,true); + Error err = export_project(export_to,true,p_dumb); if (err) { device_lock->unlock(); return err; diff --git a/platform/android/java_bind.cpp b/platform/android/java_bind.cpp new file mode 100644 index 000000000000..33ecfcffb699 --- /dev/null +++ b/platform/android/java_bind.cpp @@ -0,0 +1,5 @@ +#include "java_bind.h" + +JavaBind::JavaBind() +{ +} diff --git a/platform/android/java_bind.h b/platform/android/java_bind.h new file mode 100644 index 000000000000..ca6b4650d3f1 --- /dev/null +++ b/platform/android/java_bind.h @@ -0,0 +1,10 @@ +#ifndef JAVA_BIND_H +#define JAVA_BIND_H + +class JavaBind +{ +public: + JavaBind(); +}; + +#endif // JAVA_BIND_H diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp index 0a19e71f0859..5edcf393969e 100644 --- a/platform/bb10/export/export.cpp +++ b/platform/bb10/export/export.cpp @@ -67,11 +67,11 @@ public: virtual int get_device_count() const; virtual String get_device_name(int p_device) const; virtual String get_device_info(int p_device) const; - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return !p_debug; } virtual String get_binary_extension() const { return "bar"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -270,7 +270,7 @@ void EditorExportPlatformBB10::_fix_descriptor(Vector& p_descriptor) { -Error EditorExportPlatformBB10::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, bool p_dumb) { EditorProgress ep("export","Exporting for BlackBerry 10",104); @@ -632,7 +632,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) { } -Error EditorExportPlatformBB10::run(int p_device) { +Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) { ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER); diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index cd2e24216aed..928d12879987 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -77,11 +77,11 @@ public: virtual int get_device_count() const { return show_run?1:0; }; virtual String get_device_name(int p_device) const { return "Run in Browser"; } virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; } - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return false; } virtual String get_binary_extension() const { return "html"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -194,7 +194,7 @@ struct JSExportData { -Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_template; @@ -299,7 +299,7 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path,bool p } -Error EditorExportPlatformJavaScript::run(int p_device) { +Error EditorExportPlatformJavaScript::run(int p_device, bool p_dumb) { String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html"; Error err = export_project(path,true,""); diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index f55e90179462..087a648700d3 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -57,11 +57,11 @@ public: virtual int get_device_count() const { return 0; }; virtual String get_device_name(int p_device) const { return String(); } virtual String get_device_info(int p_device) const { return String(); } - virtual Error run(int p_device); + virtual Error run(int p_device,bool p_dumb=false); virtual bool requieres_password(bool p_debug) const { return false; } virtual String get_binary_extension() const { return "zip"; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual bool can_export(String *r_error=NULL) const; @@ -245,7 +245,7 @@ void EditorExportPlatformOSX::_fix_plist(Vector& plist,const String& p_ } } -Error EditorExportPlatformOSX::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_pkg; @@ -437,7 +437,7 @@ Error EditorExportPlatformOSX::export_project(const String& p_path,bool p_debug, } -Error EditorExportPlatformOSX::run(int p_device) { +Error EditorExportPlatformOSX::run(int p_device, bool p_dumb) { return OK; } diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp new file mode 100644 index 000000000000..1459f2c36275 --- /dev/null +++ b/scene/3d/immediate_geometry.cpp @@ -0,0 +1,102 @@ +#include "immediate_geometry.h" + + +void ImmediateGeometry::begin(Mesh::PrimitiveType p_primitive,const Ref& p_texture) { + + VS::get_singleton()->immediate_begin(im,(VS::PrimitiveType)p_primitive,p_texture.is_valid()?p_texture->get_rid():RID()); + if (p_texture.is_valid()) + cached_textures.push_back(p_texture); + +} + +void ImmediateGeometry::set_normal(const Vector3& p_normal){ + + VS::get_singleton()->immediate_normal(im,p_normal); +} + +void ImmediateGeometry::set_tangent(const Plane& p_tangent){ + + VS::get_singleton()->immediate_tangent(im,p_tangent); + +} + +void ImmediateGeometry::set_color(const Color& p_color){ + + VS::get_singleton()->immediate_color(im,p_color); + +} + +void ImmediateGeometry::set_uv(const Vector2& p_uv){ + + VS::get_singleton()->immediate_uv(im,p_uv); + +} + +void ImmediateGeometry::set_uv2(const Vector2& p_uv2){ + + VS::get_singleton()->immediate_uv2(im,p_uv2); + +} + +void ImmediateGeometry::add_vertex(const Vector3& p_vertex){ + + VS::get_singleton()->immediate_vertex(im,p_vertex); + if (empty) { + aabb.pos=p_vertex; + aabb.size=Vector3(); + } else { + aabb.expand_to(p_vertex); + } +} + +void ImmediateGeometry::end(){ + + VS::get_singleton()->immediate_end(im); + +} + +void ImmediateGeometry::clear(){ + + VS::get_singleton()->immediate_clear(im); + empty=true; + cached_textures.clear(); + +} + +AABB ImmediateGeometry::get_aabb() const { + + return aabb; +} +DVector ImmediateGeometry::get_faces(uint32_t p_usage_flags) const { + + return DVector(); +} + +void ImmediateGeometry::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("begin","primitive","texture:Texture"),&ImmediateGeometry::begin); + ObjectTypeDB::bind_method(_MD("set_normal","normal"),&ImmediateGeometry::set_normal); + ObjectTypeDB::bind_method(_MD("set_tangent","tangent"),&ImmediateGeometry::set_tangent); + ObjectTypeDB::bind_method(_MD("set_color","color"),&ImmediateGeometry::set_color); + ObjectTypeDB::bind_method(_MD("set_uv","uv"),&ImmediateGeometry::set_uv); + ObjectTypeDB::bind_method(_MD("set_uv2","uv"),&ImmediateGeometry::set_uv2); + ObjectTypeDB::bind_method(_MD("add_vertex","color"),&ImmediateGeometry::add_vertex); + ObjectTypeDB::bind_method(_MD("end"),&ImmediateGeometry::end); + ObjectTypeDB::bind_method(_MD("clear"),&ImmediateGeometry::clear); + +} + +ImmediateGeometry::ImmediateGeometry() { + + im = VisualServer::get_singleton()->immediate_create(); + set_base(im); + empty=true; + +} + + +ImmediateGeometry::~ImmediateGeometry() { + + VisualServer::get_singleton()->free(im); + +} diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h new file mode 100644 index 000000000000..2db81134c6ce --- /dev/null +++ b/scene/3d/immediate_geometry.h @@ -0,0 +1,41 @@ +#ifndef IMMEDIATE_GEOMETRY_H +#define IMMEDIATE_GEOMETRY_H + +#include "scene/3d/visual_instance.h" +#include "scene/resources/mesh.h" + +class ImmediateGeometry : public GeometryInstance { + + OBJ_TYPE(ImmediateGeometry,GeometryInstance); + + + RID im; + List > cached_textures; + bool empty; + AABB aabb; +protected: + + static void _bind_methods(); +public: + + + void begin(Mesh::PrimitiveType p_primitive,const Ref& p_texture); + void set_normal(const Vector3& p_normal); + void set_tangent(const Plane& p_tangent); + void set_color(const Color& p_color); + void set_uv(const Vector2& tex_uv); + void set_uv2(const Vector2& tex_uv); + + void add_vertex(const Vector3& p_vertex); + + void end(); + void clear(); + + virtual AABB get_aabb() const; + virtual DVector get_faces(uint32_t p_usage_flags) const; + + ImmediateGeometry(); + ~ImmediateGeometry(); +}; + +#endif // IMMEDIATE_GEOMETRY_H diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp new file mode 100644 index 000000000000..21fdb9abd316 --- /dev/null +++ b/scene/3d/sprite_3d.cpp @@ -0,0 +1,772 @@ +#include "sprite_3d.h" +#include "scene/scene_string_names.h" +#include "core_string_names.h" + + +Color SpriteBase3D::_get_color_accum() { + + if (!color_dirty) + return color_accum; + + if (parent_sprite) + color_accum=parent_sprite->_get_color_accum(); + else + color_accum=Color(1,1,1,1); + + color_accum.r*=modulate.r; + color_accum.g*=modulate.g; + color_accum.b*=modulate.b; + color_accum.a*=modulate.a; + color_dirty=false; + return color_accum; +} + +void SpriteBase3D::_propagate_color_changed() { + + if (color_dirty) + return; + + color_dirty=true; + _queue_update(); + + for (List::Element *E=children.front();E;E=E->next()) { + + E->get()->_propagate_color_changed(); + } +} + +void SpriteBase3D::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_SCENE) { + + if (!pending_update) + _im_update(); + + Node *parent=get_parent(); + if (parent) { + + parent_sprite=parent->cast_to(); + if (parent_sprite) { + pI=parent_sprite->children.push_back(this); + } + } + } + + if (p_what==NOTIFICATION_EXIT_SCENE) { + + + if (parent_sprite) { + + parent_sprite->children.erase(pI); + pI=NULL; + parent_sprite=NULL; + } + } + +} + + +void SpriteBase3D::set_centered(bool p_center) { + + centered=p_center; + _queue_update(); + +} + +bool SpriteBase3D::is_centered() const { + + return centered; +} + +void SpriteBase3D::set_offset(const Point2& p_offset) { + + offset=p_offset; + _queue_update(); + +} +Point2 SpriteBase3D::get_offset() const { + + return offset; +} + +void SpriteBase3D::set_flip_h(bool p_flip) { + + hflip=p_flip; + _queue_update(); +} +bool SpriteBase3D::is_flipped_h() const { + + return hflip; +} + +void SpriteBase3D::set_flip_v(bool p_flip) { + + vflip=p_flip; + _queue_update(); +} +bool SpriteBase3D::is_flipped_v() const { + + return vflip; +} + + + +void SpriteBase3D::set_modulate(const Color& p_color) { + + modulate=p_color; + _propagate_color_changed(); + _queue_update(); +} + +Color SpriteBase3D::get_modulate() const{ + + return modulate; +} + + +void SpriteBase3D::set_pixel_size(float p_amount) { + + pixel_size=p_amount; + _queue_update(); +} +float SpriteBase3D::get_pixel_size() const { + + return pixel_size; +} + +void SpriteBase3D::set_opacity(float p_amount) { + + opacity=p_amount; + _queue_update(); +} +float SpriteBase3D::get_opacity() const { + + return opacity; +} + + +void SpriteBase3D::set_axis(Vector3::Axis p_axis) { + + axis=p_axis; + _queue_update(); +} +Vector3::Axis SpriteBase3D::get_axis() const { + + return axis; +} + + + +void SpriteBase3D::_im_update() { + + + _draw(); + + + pending_update=false; + + //texture->draw_rect_region(ci,dst_rect,src_rect,modulate); + +} + +void SpriteBase3D::_queue_update(){ + + if (pending_update) + return; + + pending_update=true; + call_deferred(SceneStringNames::get_singleton()->_im_update); +} + + +AABB SpriteBase3D::get_aabb() const { + + return aabb; +} +DVector SpriteBase3D::get_faces(uint32_t p_usage_flags) const { + + return DVector(); + +} + +void SpriteBase3D::set_draw_flag(DrawFlags p_flag,bool p_enable) { + + ERR_FAIL_INDEX(p_flag,FLAG_MAX); + flags[p_flag]=p_enable; + _queue_update(); +} + +bool SpriteBase3D::get_draw_flag(DrawFlags p_flag) const{ + ERR_FAIL_INDEX_V(p_flag,FLAG_MAX,false); + return flags[p_flag]; +} + +void SpriteBase3D::set_alpha_cut_mode(AlphaCutMode p_mode){ + + ERR_FAIL_INDEX(p_mode,3); + alpha_cut=p_mode; + _queue_update(); + +} + +SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const{ + + return alpha_cut; +} + + +void SpriteBase3D::_bind_methods() { + + + ObjectTypeDB::bind_method(_MD("set_centered","centered"),&SpriteBase3D::set_centered); + ObjectTypeDB::bind_method(_MD("is_centered"),&SpriteBase3D::is_centered); + + ObjectTypeDB::bind_method(_MD("set_offset","offset"),&SpriteBase3D::set_offset); + ObjectTypeDB::bind_method(_MD("get_offset"),&SpriteBase3D::get_offset); + + ObjectTypeDB::bind_method(_MD("set_flip_h","flip_h"),&SpriteBase3D::set_flip_h); + ObjectTypeDB::bind_method(_MD("is_flipped_h"),&SpriteBase3D::is_flipped_h); + + ObjectTypeDB::bind_method(_MD("set_flip_v","flip_v"),&SpriteBase3D::set_flip_v); + ObjectTypeDB::bind_method(_MD("is_flipped_v"),&SpriteBase3D::is_flipped_v); + + + ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&SpriteBase3D::set_modulate); + ObjectTypeDB::bind_method(_MD("get_modulate"),&SpriteBase3D::get_modulate); + + ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&SpriteBase3D::set_opacity); + ObjectTypeDB::bind_method(_MD("get_opacity"),&SpriteBase3D::get_opacity); + + ObjectTypeDB::bind_method(_MD("set_pixel_size","pixel_size"),&SpriteBase3D::set_pixel_size); + ObjectTypeDB::bind_method(_MD("get_pixel_size"),&SpriteBase3D::get_pixel_size); + + ObjectTypeDB::bind_method(_MD("set_axis","axis"),&SpriteBase3D::set_axis); + ObjectTypeDB::bind_method(_MD("get_axis"),&SpriteBase3D::get_axis); + + ObjectTypeDB::bind_method(_MD("set_draw_flag","flag","enabled"),&SpriteBase3D::set_draw_flag); + ObjectTypeDB::bind_method(_MD("get_draw_flag","flag"),&SpriteBase3D::get_draw_flag); + + ObjectTypeDB::bind_method(_MD("set_alpha_cut_mode","mode"),&SpriteBase3D::set_alpha_cut_mode); + ObjectTypeDB::bind_method(_MD("get_alpha_cut_mode"),&SpriteBase3D::get_alpha_cut_mode); + + ObjectTypeDB::bind_method(_MD("get_item_rect"),&SpriteBase3D::get_item_rect); + + ObjectTypeDB::bind_method(_MD("_queue_update"),&SpriteBase3D::_queue_update); + ObjectTypeDB::bind_method(_MD("_im_update"),&SpriteBase3D::_im_update); + + + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); + ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h")); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v")); + ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate")); + ADD_PROPERTY( PropertyInfo( Variant::REAL, "opacity",PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_opacity"),_SCS("get_opacity")); + ADD_PROPERTY( PropertyInfo( Variant::REAL, "pixel_size",PROPERTY_HINT_RANGE,"0.0001,128,0.0001"), _SCS("set_pixel_size"),_SCS("get_pixel_size")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "axis",PROPERTY_HINT_ENUM,"X-Axis,Y-Axis,Z-Axis"), _SCS("set_axis"),_SCS("get_axis")); + ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "flags/transparent"), _SCS("set_draw_flag"),_SCS("get_draw_flag"),FLAG_TRANSPARENT); + ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "flags/shaded"), _SCS("set_draw_flag"),_SCS("get_draw_flag"),FLAG_SHADED); + ADD_PROPERTY( PropertyInfo( Variant::INT, "flags/alpha_cut",PROPERTY_HINT_ENUM,"Disabled,Discard,Opaque Pre-Pass"), _SCS("set_alpha_cut_mode"),_SCS("get_alpha_cut_mode")); + + + BIND_CONSTANT( FLAG_TRANSPARENT ); + BIND_CONSTANT( FLAG_SHADED ); + BIND_CONSTANT( FLAG_MAX ); + + BIND_CONSTANT( ALPHA_CUT_DISABLED ); + BIND_CONSTANT( ALPHA_CUT_DISCARD ); + BIND_CONSTANT( ALPHA_CUT_OPAQUE_PREPASS ); +} + + + + +SpriteBase3D::SpriteBase3D() { + + color_dirty=true; + centered=true; + hflip=false; + vflip=false; + parent_sprite=NULL; + pI=NULL; + + for(int i=0;i<4;i++) + flags[i]=i==FLAG_TRANSPARENT; + + axis=Vector3::AXIS_Z; + pixel_size=0.01; + modulate=Color(1,1,1,1); + pending_update=false; + opacity=1.0; + immediate = VisualServer::get_singleton()->immediate_create(); + set_base(immediate); +} + + +SpriteBase3D::~SpriteBase3D() { + + VisualServer::get_singleton()->free(immediate); +} + + +/////////////////////////////////////////// + + +void Sprite3D::_draw() { + + RID immediate = get_immediate(); + + VS::get_singleton()->immediate_clear(immediate); + if (!texture.is_valid()) + return; //no texuture no life + Vector2 tsize = texture->get_size(); + if (tsize.x==0 || tsize.y==0) + return; + + Size2i s; + Rect2i src_rect; + + if (region) { + + s=region_rect.size; + src_rect=region_rect; + } else { + s = texture->get_size(); + s=s/Size2i(hframes,vframes); + + src_rect.size=s; + src_rect.pos.x+=(frame%hframes)*s.x; + src_rect.pos.y+=(frame/hframes)*s.y; + + } + + Point2i ofs=get_offset(); + if (is_centered()) + ofs-=s/2; + + Rect2i dst_rect(ofs,s); + + + Rect2 final_rect; + Rect2 final_src_rect; + if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect)) + return; + + + if (final_rect.size.x==0 || final_rect.size.y==0) + return; + + Color color=_get_color_accum(); + color.a*=get_opacity(); + + float pixel_size=get_pixel_size(); + + Vector2 vertices[4]={ + + (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size, + (final_rect.pos+final_rect.size) * pixel_size, + (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size, + final_rect.pos * pixel_size, + + + }; + Vector2 uvs[4]={ + final_src_rect.pos / tsize, + (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize, + (final_src_rect.pos+final_src_rect.size) / tsize, + (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize, + }; + + if (is_flipped_h()) { + SWAP(uvs[0],uvs[1]); + SWAP(uvs[2],uvs[3]); + } + if (is_flipped_v()) { + + SWAP(uvs[0],uvs[3]); + SWAP(uvs[1],uvs[2]); + } + + + Vector3 normal; + int axis = get_axis(); + normal[axis]=1.0; + + RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS); + VS::get_singleton()->immediate_set_material(immediate,mat); + + VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid()); + + int x_axis = ((axis + 1) % 3); + int y_axis = ((axis + 2) % 3); + + AABB aabb; + + for(int i=0;i<4;i++) { + VS::get_singleton()->immediate_normal(immediate,normal); + VS::get_singleton()->immediate_color(immediate,color); + VS::get_singleton()->immediate_uv(immediate,uvs[i]); + + Vector3 vtx; + vtx[x_axis]=vertices[i][x_axis]; + vtx[y_axis]=vertices[i][y_axis]; + VS::get_singleton()->immediate_vertex(immediate,vtx); + if (i==0) { + aabb.pos=vtx; + aabb.size=Vector3(); + } else { + aabb.expand_to(vtx); + } + } + set_aabb(aabb); + VS::get_singleton()->immediate_end(immediate); + + +} + +void Sprite3D::set_texture(const Ref& p_texture) { + + if (p_texture==texture) + return; + if (texture.is_valid()) { + texture->disconnect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_queue_update); + } + texture=p_texture; + if (texture.is_valid()) { + texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites + texture->connect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_queue_update); + } + _queue_update(); + +} + +Ref Sprite3D::get_texture() const { + + return texture; +} + +void Sprite3D::set_region(bool p_region) { + + if (p_region==region) + return; + + region=p_region; + _queue_update(); +} + +bool Sprite3D::is_region() const{ + + return region; +} + +void Sprite3D::set_region_rect(const Rect2& p_region_rect) { + + bool changed=region_rect!=p_region_rect; + region_rect=p_region_rect; + if (region && changed) { + _queue_update(); + } +} + +Rect2 Sprite3D::get_region_rect() const { + + return region_rect; +} + +void Sprite3D::set_frame(int p_frame) { + + ERR_FAIL_INDEX(p_frame,vframes*hframes); + + if (frame != p_frame) + + frame=p_frame; +} + +int Sprite3D::get_frame() const { + + return frame; +} + +void Sprite3D::set_vframes(int p_amount) { + + ERR_FAIL_COND(p_amount<1); + vframes=p_amount; + _queue_update(); + _change_notify("frame"); +} +int Sprite3D::get_vframes() const { + + return vframes; +} + +void Sprite3D::set_hframes(int p_amount) { + + ERR_FAIL_COND(p_amount<1); + hframes=p_amount; + _queue_update(); + _change_notify("frame"); +} +int Sprite3D::get_hframes() const { + + return hframes; +} + +Rect2 Sprite3D::get_item_rect() const { + + if (texture.is_null()) + return Rect2(0,0,1,1); + //if (texture.is_null()) + // return CanvasItem::get_item_rect(); + + Size2i s; + + if (region) { + + s=region_rect.size; + } else { + s = texture->get_size(); + s=s/Point2(hframes,vframes); + } + + Point2i ofs=get_offset(); + if (is_centered()) + ofs-=s/2; + + if (s==Size2(0,0)) + s=Size2(1,1); + + return Rect2(ofs,s); +} + +void Sprite3D::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_texture","texture:Texture"),&Sprite3D::set_texture); + ObjectTypeDB::bind_method(_MD("get_texture:Texture"),&Sprite3D::get_texture); + + ObjectTypeDB::bind_method(_MD("set_region","enabled"),&Sprite3D::set_region); + ObjectTypeDB::bind_method(_MD("is_region"),&Sprite3D::is_region); + + ObjectTypeDB::bind_method(_MD("set_region_rect","rect"),&Sprite3D::set_region_rect); + ObjectTypeDB::bind_method(_MD("get_region_rect"),&Sprite3D::get_region_rect); + + ObjectTypeDB::bind_method(_MD("set_frame","frame"),&Sprite3D::set_frame); + ObjectTypeDB::bind_method(_MD("get_frame"),&Sprite3D::get_frame); + + ObjectTypeDB::bind_method(_MD("set_vframes","vframes"),&Sprite3D::set_vframes); + ObjectTypeDB::bind_method(_MD("get_vframes"),&Sprite3D::get_vframes); + + ObjectTypeDB::bind_method(_MD("set_hframes","hframes"),&Sprite3D::set_hframes); + ObjectTypeDB::bind_method(_MD("get_hframes"),&Sprite3D::get_hframes); + + ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); + ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); + +} + +Sprite3D::Sprite3D() { + + + region=false; + frame=0; + vframes=1; + hframes=1; + +} + +//////////////////////////////////////// + + +void AnimatedSprite3D::_draw() { + + RID immediate = get_immediate(); + VS::get_singleton()->immediate_clear(immediate); + + if (!frames.is_valid() || !frames->get_frame_count() || frame<0 || frame>=frames->get_frame_count()) { + return; + } + + Ref texture = frames->get_frame(frame); + if (!texture.is_valid()) + return; //no texuture no life + Vector2 tsize = texture->get_size(); + if (tsize.x==0 || tsize.y==0) + return; + + Size2i s=tsize; + Rect2i src_rect; + + src_rect.size=s; + + Point2i ofs=get_offset(); + if (is_centered()) + ofs-=s/2; + + Rect2i dst_rect(ofs,s); + + + Rect2 final_rect; + Rect2 final_src_rect; + if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect)) + return; + + + if (final_rect.size.x==0 || final_rect.size.y==0) + return; + + Color color=_get_color_accum(); + color.a*=get_opacity(); + + float pixel_size=get_pixel_size(); + + Vector2 vertices[4]={ + + (final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size, + (final_rect.pos+final_rect.size) * pixel_size, + (final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size, + final_rect.pos * pixel_size, + + + }; + Vector2 uvs[4]={ + final_src_rect.pos / tsize, + (final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize, + (final_src_rect.pos+final_src_rect.size) / tsize, + (final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize, + }; + + if (is_flipped_h()) { + SWAP(uvs[0],uvs[1]); + SWAP(uvs[2],uvs[3]); + } + if (is_flipped_v()) { + + SWAP(uvs[0],uvs[3]); + SWAP(uvs[1],uvs[2]); + } + + + Vector3 normal; + int axis = get_axis(); + normal[axis]=1.0; + + RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS); + VS::get_singleton()->immediate_set_material(immediate,mat); + + VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid()); + + int x_axis = ((axis + 1) % 3); + int y_axis = ((axis + 2) % 3); + + AABB aabb; + + for(int i=0;i<4;i++) { + VS::get_singleton()->immediate_normal(immediate,normal); + VS::get_singleton()->immediate_color(immediate,color); + VS::get_singleton()->immediate_uv(immediate,uvs[i]); + + Vector3 vtx; + vtx[x_axis]=vertices[i][x_axis]; + vtx[y_axis]=vertices[i][y_axis]; + VS::get_singleton()->immediate_vertex(immediate,vtx); + if (i==0) { + aabb.pos=vtx; + aabb.size=Vector3(); + } else { + aabb.expand_to(vtx); + } + } + set_aabb(aabb); + VS::get_singleton()->immediate_end(immediate); + +} + +void AnimatedSprite3D::_bind_methods(){ + + ObjectTypeDB::bind_method(_MD("set_sprite_frames","sprite_frames:SpriteFrames"),&AnimatedSprite3D::set_sprite_frames); + ObjectTypeDB::bind_method(_MD("get_sprite_frames:Texture"),&AnimatedSprite3D::get_sprite_frames); + ObjectTypeDB::bind_method(_MD("set_frame","frame"),&AnimatedSprite3D::set_frame); + ObjectTypeDB::bind_method(_MD("get_frame"),&AnimatedSprite3D::get_frame); + + ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); + ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); + +} + + + + +void AnimatedSprite3D::set_sprite_frames(const Ref& p_sprite_frames) { + + + if (frames==p_sprite_frames) + return; + + if (frames.is_valid()) + frames->disconnect("changed",this,"_queue_update"); + frames=p_sprite_frames; + if (frames.is_valid()) + frames->connect("changed",this,"_queue_update"); + + if (!frames.is_valid() || frame >=frames->get_frame_count()) { + frame=0; + + } + _queue_update(); + +} + +Ref AnimatedSprite3D::get_sprite_frames() const{ + + return frames; +} + +void AnimatedSprite3D::set_frame(int p_frame){ + + if (frames.is_null()) + return; + + ERR_FAIL_INDEX(p_frame,frames->get_frame_count()); + + if (frame==p_frame) + return; + + frame=p_frame; + _queue_update(); + +} +int AnimatedSprite3D::get_frame() const{ + + return frame; +} + +Rect2 AnimatedSprite3D::get_item_rect() const { + + if (!frames.is_valid() || !frames->get_frame_count() || frame<0 || frame>=frames->get_frame_count()) { + return Rect2(0,0,1,1); + } + + Ref t = frames->get_frame(frame); + if (t.is_null()) + return Rect2(0,0,1,1); + Size2i s = t->get_size(); + + Point2i ofs=get_offset(); + if (is_centered()) + ofs-=s/2; + + if (s==Size2(0,0)) + s=Size2(1,1); + + return Rect2(ofs,s); +} + + + +AnimatedSprite3D::AnimatedSprite3D() { + + frame=0; +} + diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h new file mode 100644 index 000000000000..1330cd1c3078 --- /dev/null +++ b/scene/3d/sprite_3d.h @@ -0,0 +1,191 @@ +#ifndef SPRITE_3D_H +#define SPRITE_3D_H + +#include "scene/3d/visual_instance.h" +#include "scene/2d/animated_sprite.h" + + +class SpriteBase3D : public VisualInstance { + + OBJ_TYPE(SpriteBase3D,VisualInstance); +public: + + enum DrawFlags { + FLAG_TRANSPARENT, + FLAG_SHADED, + FLAG_MAX + + }; + + enum AlphaCutMode { + ALPHA_CUT_DISABLED, + ALPHA_CUT_DISCARD, + ALPHA_CUT_OPAQUE_PREPASS + }; + +private: + + + bool color_dirty; + Color color_accum; + + SpriteBase3D *parent_sprite; + List children; + List::Element *pI; + + bool centered; + Point2 offset; + + bool hflip; + bool vflip; + + + Color modulate; + float opacity; + + Vector3::Axis axis; + float pixel_size; + AABB aabb; + + RID immediate; + + bool flags[FLAG_MAX]; + AlphaCutMode alpha_cut; + bool pending_update; + void _im_update(); + + + void _propagate_color_changed(); + +protected: + + Color _get_color_accum(); + void _notification(int p_what); + static void _bind_methods(); + virtual void _draw()=0; + _FORCE_INLINE_ void set_aabb(const AABB& p_aabb) { aabb=p_aabb; } + _FORCE_INLINE_ RID& get_immediate() { return immediate; } + void _queue_update(); +public: + + void set_centered(bool p_center); + bool is_centered() const; + + void set_offset(const Point2& p_offset); + Point2 get_offset() const; + + void set_flip_h(bool p_flip); + bool is_flipped_h() const; + + void set_flip_v(bool p_flip); + bool is_flipped_v() const; + + void set_region(bool p_region); + bool is_region() const; + + void set_region_rect(const Rect2& p_region_rect); + Rect2 get_region_rect() const; + + void set_modulate(const Color& p_color); + Color get_modulate() const; + + void set_opacity(float p_amount); + float get_opacity() const; + + void set_pixel_size(float p_amount); + float get_pixel_size() const; + + void set_axis(Vector3::Axis p_amount); + Vector3::Axis get_axis() const; + + void set_draw_flag(DrawFlags p_flag,bool p_enable); + bool get_draw_flag(DrawFlags p_flag) const; + + void set_alpha_cut_mode(AlphaCutMode p_mode); + AlphaCutMode get_alpha_cut_mode() const; + + virtual Rect2 get_item_rect() const=0; + + virtual AABB get_aabb() const; + virtual DVector get_faces(uint32_t p_usage_flags) const; + + SpriteBase3D(); + ~SpriteBase3D(); +}; + + +class Sprite3D : public SpriteBase3D { + + OBJ_TYPE(Sprite3D,SpriteBase3D); + Ref texture; + + + bool region; + Rect2 region_rect; + + int frame; + + int vframes; + int hframes; +protected: + virtual void _draw(); + static void _bind_methods(); +public: + + + + void set_texture(const Ref& p_texture); + Ref get_texture() const; + + void set_region(bool p_region); + bool is_region() const; + + void set_region_rect(const Rect2& p_region_rect); + Rect2 get_region_rect() const; + + void set_frame(int p_frame); + int get_frame() const; + + void set_vframes(int p_amount); + int get_vframes() const; + + void set_hframes(int p_amount); + int get_hframes() const; + + virtual Rect2 get_item_rect() const; + + Sprite3D(); +// ~Sprite3D(); +}; + +class AnimatedSprite3D : public SpriteBase3D { + + OBJ_TYPE(AnimatedSprite3D,SpriteBase3D); + Ref frames; + + + int frame; + +protected: + virtual void _draw(); + static void _bind_methods(); +public: + + + + void set_sprite_frames(const Ref& p_sprite_frames); + Ref get_sprite_frames() const; + + void set_frame(int p_frame); + int get_frame() const; + + + virtual Rect2 get_item_rect() const; + + AnimatedSprite3D(); +// ~AnimatedSprite3D(); +}; + +VARIANT_ENUM_CAST(SpriteBase3D::DrawFlags); +VARIANT_ENUM_CAST(SpriteBase3D::AlphaCutMode); +#endif // SPRITE_3D_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index b30ad2d71f85..f3d757b601eb 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -189,6 +189,8 @@ #include "scene/3d/multimesh_instance.h" #include "scene/3d/baked_light.h" #include "scene/3d/ray_cast.h" +#include "scene/3d/immediate_geometry.h" +#include "scene/3d/sprite_3d.h" #include "scene/3d/spatial_sample_player.h" #include "scene/3d/spatial_stream_player.h" #include "scene/3d/proximity_group.h" @@ -372,6 +374,9 @@ void register_scene_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 0c55d22dbeb2..99447c0a0e7b 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -109,9 +109,13 @@ void Environment::_bind_methods() { ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/cubemap",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_CUBEMAP); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/energy",PROPERTY_HINT_RANGE,"0,128,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_ENERGY); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/scale",PROPERTY_HINT_RANGE,"0.001,16,0.001"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_SCALE); + ADD_PROPERTYI( PropertyInfo(Variant::REAL,"background/glow",PROPERTY_HINT_RANGE,"0.00,8,0.01"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_GLOW); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"glow/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_GLOW); ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_passes",PROPERTY_HINT_RANGE,"1,4,1"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_PASSES); + ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/blur_scale",PROPERTY_HINT_RANGE,"0.01,4,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_SCALE); + ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/blur_strength",PROPERTY_HINT_RANGE,"0.01,4,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_STRENGTH); + ADD_PROPERTYI( PropertyInfo(Variant::INT,"glow/blur_blend_mode",PROPERTY_HINT_ENUM,"Additive,Screen,SoftLight"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLUR_BLEND_MODE); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/bloom",PROPERTY_HINT_RANGE,"0,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLOOM); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"glow/bloom_treshold",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GLOW_BLOOM_TRESHOLD); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"dof_blur/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_DOF_BLUR); @@ -180,6 +184,7 @@ void Environment::_bind_methods() { BIND_CONSTANT( BG_PARAM_TEXTURE ); BIND_CONSTANT( BG_PARAM_CUBEMAP ); BIND_CONSTANT( BG_PARAM_ENERGY ); + BIND_CONSTANT( BG_PARAM_GLOW ); BIND_CONSTANT( BG_PARAM_MAX ); @@ -193,7 +198,14 @@ void Environment::_bind_methods() { BIND_CONSTANT( FX_MAX ); + BIND_CONSTANT( FX_BLUR_BLEND_MODE_ADDITIVE ); + BIND_CONSTANT( FX_BLUR_BLEND_MODE_SCREEN ); + BIND_CONSTANT( FX_BLUR_BLEND_MODE_SOFTLIGHT ); + BIND_CONSTANT( FX_PARAM_GLOW_BLUR_PASSES ); + BIND_CONSTANT( FX_PARAM_GLOW_BLUR_SCALE ); + BIND_CONSTANT( FX_PARAM_GLOW_BLUR_STRENGTH ); + BIND_CONSTANT( FX_PARAM_GLOW_BLUR_BLEND_MODE ); BIND_CONSTANT( FX_PARAM_GLOW_BLOOM); BIND_CONSTANT( FX_PARAM_GLOW_BLOOM_TRESHOLD); BIND_CONSTANT( FX_PARAM_DOF_BLUR_PASSES ); @@ -229,11 +241,14 @@ Environment::Environment() { set_background_param(BG_PARAM_CUBEMAP,Ref()); set_background_param(BG_PARAM_ENERGY,1.0); set_background_param(BG_PARAM_SCALE,1.0); + set_background_param(BG_PARAM_GLOW,0.0); for(int i=0;ifixed_material_set_flag(material,(VS::FixedMaterialFlags)p_flag,p_value); } bool FixedMaterial::get_fixed_flag(FixedFlag p_flag) const { - ERR_FAIL_INDEX_V(p_flag,3,false); + ERR_FAIL_INDEX_V(p_flag,4,false); return fixed_flags[p_flag]; } @@ -419,6 +422,7 @@ void FixedMaterial::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_ALPHA); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_color_array" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_COLOR_ARRAY); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_point_size" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_POINT_SIZE); + ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/discard_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_DISCARD_ALPHA); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/diffuse" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DIFFUSE); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/specular", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR ); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/emission", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_EMISSION ); @@ -457,6 +461,7 @@ void FixedMaterial::_bind_methods() { BIND_CONSTANT( FLAG_USE_ALPHA ); BIND_CONSTANT( FLAG_USE_COLOR_ARRAY ); BIND_CONSTANT( FLAG_USE_POINT_SIZE ); + BIND_CONSTANT( FLAG_DISCARD_ALPHA ); } diff --git a/scene/resources/material.h b/scene/resources/material.h index 1f2afb70b9cf..2057b3cac9f9 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -85,6 +85,7 @@ public: HINT_OPAQUE_PRE_PASS=VS::MATERIAL_HINT_OPAQUE_PRE_PASS, HINT_NO_SHADOW=VS::MATERIAL_HINT_NO_SHADOW, HINT_NO_DEPTH_DRAW=VS::MATERIAL_HINT_NO_DEPTH_DRAW, + HINT_NO_DEPTH_DRAW_FOR_ALPHA=VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA, HINT_MAX=VS::MATERIAL_HINT_MAX }; @@ -159,6 +160,7 @@ public: FLAG_USE_ALPHA=VS::FIXED_MATERIAL_FLAG_USE_ALPHA, FLAG_USE_COLOR_ARRAY=VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY, FLAG_USE_POINT_SIZE=VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE, + FLAG_DISCARD_ALPHA=VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA }; private: diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 5402a28d9290..5b31ba1f1ba1 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -53,6 +53,13 @@ void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate); } +bool Texture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const { + + r_rect=p_rect; + r_src_rect=p_src_rect; + + return true; +} void Texture::_bind_methods() { @@ -609,6 +616,42 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate); } +bool AtlasTexture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const { + + Rect2 rc=region; + + if (!atlas.is_valid()) + return false; + + Rect2 src=p_src_rect; + src.pos+=(rc.pos-margin.pos); + Rect2 src_c = rc.clip(src); + if (src_c.size==Size2()) + return false; + Vector2 ofs = (src_c.pos-src.pos); + + Vector2 scale = p_rect.size / p_src_rect.size; + if(scale.x < 0) + { + float mx = (margin.size.width - margin.pos.x); + mx -= margin.pos.x; + ofs.x = -(ofs.x + mx); + } + if(scale.y < 0) + { + float my = margin.size.height - margin.pos.y; + my -= margin.pos.y; + ofs.y = -(ofs.y + my); + } + Rect2 dr( p_rect.pos+ofs*scale,src_c.size*scale ); + + + + r_rect=dr; + r_src_rect=src_c; + return true; +} + AtlasTexture::AtlasTexture() { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index b780d70e1a84..86ff246498d1 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -70,6 +70,7 @@ public: 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 bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const; @@ -191,6 +192,7 @@ public: 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 bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const; AtlasTexture(); diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 5c54bd74e3cc..a8e4c80f8964 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -137,5 +137,7 @@ SceneStringNames::SceneStringNames() { drop_data = StaticCString::create("drop_data"); can_drop_data = StaticCString::create("can_drop_data"); + _im_update = StaticCString::create("_im_update"); + _queue_update = StaticCString::create("_queue_update"); } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 6a4e58ed5430..2286712250c5 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -145,6 +145,10 @@ public: StringName play_play; + StringName _im_update; + StringName _queue_update; + + }; diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp index 2de49d3d8104..e21848eac275 100644 --- a/servers/visual/rasterizer.cpp +++ b/servers/visual/rasterizer.cpp @@ -157,6 +157,9 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { if (p_key.use_alpha) { code+="DIFFUSE_ALPHA=diffuse;\n"; + if (p_key.discard_alpha) { + code+="DISCARD=diffuse.a<0.5;\n"; + } } else { code+="DIFFUSE=diffuse.rgb;\n"; } @@ -262,6 +265,7 @@ void Rasterizer::_free_shader(const FixedMaterialShaderKey& p_key) { void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags p_flag, bool p_enabled) { + Map::Element *E = fixed_materials.find(p_material); ERR_FAIL_COND(!E); FixedMaterial &fm=*E->get(); @@ -271,6 +275,7 @@ void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: fm.use_alpha=p_enabled; break; case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: fm.use_color_array=p_enabled; break; case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: fm.use_pointsize=p_enabled; break; + case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: fm.discard_alpha=p_enabled; break; } if (!fm.dirty_list.in_list()) @@ -288,6 +293,7 @@ bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedMaterialFlags case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: return fm.use_alpha;; break; case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: return fm.use_color_array;; break; case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: return fm.use_pointsize;; break; + case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: return fm.discard_alpha;; break; } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 783231d2e504..a3cdff9859f7 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -55,6 +55,7 @@ protected: bool use_alpha:1; bool use_color_array:1; bool use_pointsize:1; + bool discard_alpha:1; bool valid:1; }; @@ -80,6 +81,7 @@ protected: RID self; bool use_alpha; bool use_color_array; + bool discard_alpha; bool use_pointsize; float point_size; Transform uv_xform; @@ -100,6 +102,7 @@ protected: k.use_alpha=use_alpha; k.use_color_array=use_color_array; k.use_pointsize=use_pointsize; + k.discard_alpha=discard_alpha; k.detail_blend=detail_blend; k.valid=true; for(int i=0;imaterial=p_material; + +} + +RID RasterizerDummy::immediate_get_material(RID p_immediate) const { + + const Immediate *im = immediate_owner.get(p_immediate); + ERR_FAIL_COND_V(!im,RID()); + return im->material; + +} /* PARTICLES API */ @@ -1627,6 +1695,12 @@ bool RasterizerDummy::is_mesh(const RID& p_rid) const { return mesh_owner.owns(p_rid); } + +bool RasterizerDummy::is_immediate(const RID& p_rid) const { + + return immediate_owner.owns(p_rid); +} + bool RasterizerDummy::is_multimesh(const RID& p_rid) const { return multimesh_owner.owns(p_rid); @@ -1703,6 +1777,12 @@ void RasterizerDummy::free(const RID& p_rid) { multimesh_owner.free(p_rid); memdelete(multimesh); + } else if (immediate_owner.owns(p_rid)) { + + Immediate *immediate = immediate_owner.get(p_rid); + immediate_owner.free(p_rid); + memdelete(immediate); + } else if (particles_owner.owns(p_rid)) { Particles *particles = particles_owner.get(p_rid); diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 880e19c9b0aa..b683a25bdcac 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -231,8 +231,18 @@ class RasterizerDummy : public Rasterizer { }; + mutable RID_Owner multimesh_owner; + struct Immediate { + + + RID material; + int empty; + }; + + mutable RID_Owner immediate_owner; + struct Particles : public Geometry { ParticleSystemSW data; // software particle system @@ -490,6 +500,23 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; + /* IMMEDIATE API */ + + virtual RID immediate_create(); + virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID()); + virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex); + virtual void immediate_normal(RID p_immediate,const Vector3& p_normal); + virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent); + virtual void immediate_color(RID p_immediate,const Color& p_color); + virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv); + virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv); + virtual void immediate_end(RID p_immediate); + virtual void immediate_clear(RID p_immediate); + virtual void immediate_set_material(RID p_immediate,RID p_material); + virtual RID immediate_get_material(RID p_immediate) const; + + virtual AABB immediate_get_aabb(RID p_mesh) const; + /* PARTICLES API */ virtual RID particles_create(); @@ -647,6 +674,7 @@ public: virtual void add_mesh( const RID& p_mesh, const InstanceData *p_data); virtual void add_multimesh( const RID& p_multimesh, const InstanceData *p_data); + virtual void add_immediate( const RID& p_immediate, const InstanceData *p_data) {} virtual void add_particles( const RID& p_particle_instance, const InstanceData *p_data); virtual void end_scene(); @@ -692,6 +720,7 @@ public: virtual bool is_texture(const RID& p_rid) const; virtual bool is_material(const RID& p_rid) const; virtual bool is_mesh(const RID& p_rid) const; + virtual bool is_immediate(const RID& p_rid) const; virtual bool is_multimesh(const RID& p_rid) const; virtual bool is_particles(const RID &p_beam) const; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 3061c2ddffa9..cdc1f678e728 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -1034,7 +1034,7 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::fragment_builtins_defs[]={ { "SPEC_EXP", TYPE_FLOAT}, { "GLOW", TYPE_FLOAT}, { "SHADE_PARAM", TYPE_FLOAT}, - { "DISCARD", TYPE_FLOAT}, + { "DISCARD", TYPE_BOOL}, { "SCREEN_UV", TYPE_VEC2}, { "POINT_COORD", TYPE_VEC2}, { "INV_CAMERA_MATRIX", TYPE_MAT4}, diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 6b74b34ba17c..bffc1c43fecb 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -519,6 +519,72 @@ int VisualServerRaster::multimesh_get_visible_instances(RID p_multimesh) const { } +/* IMMEDIATE API */ + + +RID VisualServerRaster::immediate_create() { + + return rasterizer->immediate_create(); +} + +void VisualServerRaster::immediate_begin(RID p_immediate,PrimitiveType p_primitive,RID p_texture){ + + rasterizer->immediate_begin(p_immediate,p_primitive,p_texture); +} +void VisualServerRaster::immediate_vertex(RID p_immediate,const Vector3& p_vertex){ + + rasterizer->immediate_vertex(p_immediate,p_vertex); + +} +void VisualServerRaster::immediate_normal(RID p_immediate,const Vector3& p_normal){ + + rasterizer->immediate_normal(p_immediate,p_normal); + +} +void VisualServerRaster::immediate_tangent(RID p_immediate,const Plane& p_tangent){ + + rasterizer->immediate_tangent(p_immediate,p_tangent); + +} +void VisualServerRaster::immediate_color(RID p_immediate,const Color& p_color){ + + rasterizer->immediate_color(p_immediate,p_color); + +} +void VisualServerRaster::immediate_uv(RID p_immediate,const Vector2& p_uv){ + + rasterizer->immediate_uv(p_immediate,p_uv); + +} +void VisualServerRaster::immediate_uv2(RID p_immediate,const Vector2& p_uv2){ + + rasterizer->immediate_uv2(p_immediate,p_uv2); + +} +void VisualServerRaster::immediate_end(RID p_immediate){ + + VS_CHANGED; + _dependency_queue_update(p_immediate,true); + rasterizer->immediate_end(p_immediate); + +} +void VisualServerRaster::immediate_clear(RID p_immediate){ + + VS_CHANGED; + _dependency_queue_update(p_immediate,true); + rasterizer->immediate_clear(p_immediate); + +} + +void VisualServerRaster::immediate_set_material(RID p_immediate,RID p_material) { + + rasterizer->immediate_set_material(p_immediate,p_material); +} + +RID VisualServerRaster::immediate_get_material(RID p_immediate) const { + + return rasterizer->immediate_get_material(p_immediate); +} /* PARTICLES API */ @@ -1705,6 +1771,8 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) { instance->data.morph_values.resize( rasterizer->mesh_get_morph_target_count(p_base)); } else if (rasterizer->is_multimesh(p_base)) { instance->base_type=INSTANCE_MULTIMESH; + } else if (rasterizer->is_immediate(p_base)) { + instance->base_type=INSTANCE_IMMEDIATE; } else if (rasterizer->is_particles(p_base)) { instance->base_type=INSTANCE_PARTICLES; instance->particles_info=memnew( Instance::ParticlesInfo ); @@ -2467,6 +2535,12 @@ void VisualServerRaster::_update_instance_aabb(Instance *p_instance) { new_aabb = rasterizer->multimesh_get_aabb(p_instance->base_rid); + } break; + case VisualServer::INSTANCE_IMMEDIATE: { + + new_aabb = rasterizer->immediate_get_aabb(p_instance->base_rid); + + } break; case VisualServer::INSTANCE_PARTICLES: { @@ -3498,6 +3572,9 @@ void VisualServerRaster::_instance_draw(Instance *p_instance) { case INSTANCE_MULTIMESH: { rasterizer->add_multimesh(p_instance->base_rid, &p_instance->data); } break; + case INSTANCE_IMMEDIATE: { + rasterizer->add_immediate(p_instance->base_rid, &p_instance->data); + } break; case INSTANCE_PARTICLES: { rasterizer->add_particles(p_instance->particles_info->instance, &p_instance->data); } break; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index c281e0b9e626..f6ef4ba6d53f 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -766,6 +766,21 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; + /* IMMEDIATE API */ + + virtual RID immediate_create(); + virtual void immediate_begin(RID p_immediate,PrimitiveType p_rimitive,RID p_texture=RID()); + virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex); + virtual void immediate_normal(RID p_immediate,const Vector3& p_normal); + virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent); + virtual void immediate_color(RID p_immediate,const Color& p_color); + virtual void immediate_uv(RID p_immediate, const Vector2& p_uv); + virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv); + virtual void immediate_end(RID p_immediate); + virtual void immediate_clear(RID p_immediate); + virtual void immediate_set_material(RID p_immediate,RID p_material); + virtual RID immediate_get_material(RID p_immediate) const; + /* PARTICLES API */ diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 87e13cb2024e..cfc4bd860541 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -741,6 +741,22 @@ public: FUNC2(multimesh_set_visible_instances,RID,int); FUNC1RC(int,multimesh_get_visible_instances,RID); + /* IMMEDIATE API */ + + + FUNC0R(RID,immediate_create); + FUNC3(immediate_begin,RID,PrimitiveType,RID); + FUNC2(immediate_vertex,RID,const Vector3&); + FUNC2(immediate_normal,RID,const Vector3&); + FUNC2(immediate_tangent,RID,const Plane&); + FUNC2(immediate_color,RID,const Color&); + FUNC2(immediate_uv,RID,const Vector2&); + FUNC2(immediate_uv2,RID,const Vector2&); + FUNC1(immediate_end,RID); + FUNC1(immediate_clear,RID); + FUNC2(immediate_set_material,RID,RID); + FUNC1RC(RID,immediate_get_material,RID); + /* PARTICLES API */ diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index a45e2c8eafff..08cc57e307b4 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -274,6 +274,55 @@ RID VisualServer::make_sphere_mesh(int p_lats,int p_lons,float p_radius) { return mesh; } + +RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_alpha, bool p_opaque_prepass) { + + int version=0; + if (p_shaded) + version=1; + if (p_transparent) + version|=2; + if (p_cut_alpha) + version|=4; + if (p_opaque_prepass) + version|=8; + if (material_2d[version].is_valid()) + return material_2d[version]; + + //not valid, make + + material_2d[version]=fixed_material_create(); + fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_ALPHA,p_transparent); + fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true); + fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_DISCARD_ALPHA,p_cut_alpha); + material_set_flag(material_2d[version],MATERIAL_FLAG_UNSHADED,!p_shaded); + material_set_flag(material_2d[version],MATERIAL_FLAG_DOUBLE_SIDED,true); + material_set_hint(material_2d[version],MATERIAL_HINT_OPAQUE_PRE_PASS,p_opaque_prepass); + fixed_material_set_texture(material_2d[version],FIXED_MATERIAL_PARAM_DIFFUSE,get_white_texture()); + //material cut alpha? + return material_2d[version]; +} + +RID VisualServer::get_white_texture() { + + if (white_texture.is_valid()) + return white_texture; + + DVector wt; + wt.resize(16*3); + { + DVector::Write w =wt.write(); + for(int i=0;i<16*3;i++) + w[i]=255; + } + Image white(4,4,0,Image::FORMAT_RGB,wt); + white_texture=texture_create(); + texture_allocate(white_texture,4,4,Image::FORMAT_RGB); + texture_set_data(white_texture,white); + return white_texture; + +} + void VisualServer::_bind_methods() { diff --git a/servers/visual_server.h b/servers/visual_server.h index e1793a230ef2..e5d1e7570204 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -56,6 +56,8 @@ class VisualServer : public Object { protected: RID _make_test_cube(); RID test_texture; + RID white_texture; + RID material_2d[16]; static VisualServer* (*create_func)(); static void _bind_methods(); @@ -189,6 +191,7 @@ public: MATERIAL_HINT_OPAQUE_PRE_PASS, MATERIAL_HINT_NO_SHADOW, MATERIAL_HINT_NO_DEPTH_DRAW, + MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA, MATERIAL_HINT_MAX }; @@ -241,6 +244,7 @@ public: FIXED_MATERIAL_FLAG_USE_ALPHA, FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY, FIXED_MATERIAL_FLAG_USE_POINT_SIZE, + FIXED_MATERIAL_FLAG_DISCARD_ALPHA, FIXED_MATERIAL_FLAG_MAX, }; @@ -360,7 +364,22 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible)=0; virtual int multimesh_get_visible_instances(RID p_multimesh) const=0; - + /* IMMEDIATE API */ + + virtual RID immediate_create()=0; + virtual void immediate_begin(RID p_immediate,PrimitiveType p_rimitive,RID p_texture=RID())=0; + virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex)=0; + virtual void immediate_normal(RID p_immediate,const Vector3& p_normal)=0; + virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent)=0; + virtual void immediate_color(RID p_immediate,const Color& p_color)=0; + virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv)=0; + virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv)=0; + virtual void immediate_end(RID p_immediate)=0; + virtual void immediate_clear(RID p_immediate)=0; + virtual void immediate_set_material(RID p_immediate,RID p_material)=0; + virtual RID immediate_get_material(RID p_immediate) const=0; + + /* PARTICLES API */ virtual RID particles_create()=0; @@ -556,6 +575,8 @@ public: virtual void portal_set_connect_range(RID p_portal, float p_range) =0; virtual float portal_get_connect_range(RID p_portal) const =0; + + /* CAMERA API */ virtual RID camera_create()=0; @@ -675,6 +696,7 @@ public: ENV_BG_PARAM_CUBEMAP, ENV_BG_PARAM_ENERGY, ENV_BG_PARAM_SCALE, + ENV_BG_PARAM_GLOW, ENV_BG_PARAM_MAX }; @@ -698,8 +720,17 @@ public: virtual void environment_set_enable_fx(RID p_env,EnvironmentFx p_effect,bool p_enabled)=0; virtual bool environment_is_fx_enabled(RID p_env,EnvironmentFx p_mode) const=0; + enum EnvironmentFxBlurBlendMode { + ENV_FX_BLUR_BLEND_MODE_ADDITIVE, + ENV_FX_BLUR_BLEND_MODE_SCREEN, + ENV_FX_BLUR_BLEND_MODE_SOFTLIGHT, + }; + enum EnvironmentFxParam { ENV_FX_PARAM_GLOW_BLUR_PASSES, + ENV_FX_PARAM_GLOW_BLUR_SCALE, + ENV_FX_PARAM_GLOW_BLUR_STRENGTH, + ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE, ENV_FX_PARAM_GLOW_BLOOM, ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD, ENV_FX_PARAM_DOF_BLUR_PASSES, @@ -756,12 +787,13 @@ public: INSTANCE_NONE, INSTANCE_MESH, INSTANCE_MULTIMESH, + INSTANCE_IMMEDIATE, INSTANCE_PARTICLES, INSTANCE_LIGHT, INSTANCE_ROOM, INSTANCE_PORTAL, - INSTANCE_GEOMETRY_MASK=(1<get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); - fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); + bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); + fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); + run_native->set_deploy_dumb(!ischecked); } break; case SETTINGS_UPDATE_ALWAYS: { @@ -3612,7 +3613,7 @@ EditorNode::EditorNode() { p->set_item_tooltip(p->get_item_index(RUN_FILE_SERVER),"Enable/Disable the File Server."); p->add_separator(); p->add_check_item("Deploy Dumb Clients",RUN_DEPLOY_DUMB_CLIENTS); - p->set_item_checked( p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),true ); + //p->set_item_checked( p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),true ); p->set_item_tooltip(p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),"Deploy dumb clients when the File Server is active."); p->connect("item_pressed",this,"_menu_option"); diff --git a/tools/editor/editor_run_native.cpp b/tools/editor/editor_run_native.cpp index a0e04814a553..be1a124fc2dc 100644 --- a/tools/editor/editor_run_native.cpp +++ b/tools/editor/editor_run_native.cpp @@ -101,7 +101,7 @@ void EditorRunNative::_run_native(int p_idx,const String& p_platform) { Ref eep = EditorImportExport::get_singleton()->get_export_platform(p_platform); ERR_FAIL_COND(eep.is_null()); - eep->run(p_idx); + eep->run(p_idx,deploy_dumb); } void EditorRunNative::_bind_methods() { @@ -109,8 +109,20 @@ void EditorRunNative::_bind_methods() { ObjectTypeDB::bind_method("_run_native",&EditorRunNative::_run_native); } +void EditorRunNative::set_deploy_dumb(bool p_enabled) { + + deploy_dumb=p_enabled; +} + +bool EditorRunNative::is_deploy_dumb_enabled() const{ + + return deploy_dumb; +} + + EditorRunNative::EditorRunNative() { set_process(true); first=true; + deploy_dumb=false; } diff --git a/tools/editor/editor_run_native.h b/tools/editor/editor_run_native.h index ca3d41126fa6..f4bda2d07d77 100644 --- a/tools/editor/editor_run_native.h +++ b/tools/editor/editor_run_native.h @@ -38,6 +38,7 @@ class EditorRunNative : public HBoxContainer { Map menus; bool first; + bool deploy_dumb; void _run_native(int p_idx,const String& p_platform); @@ -46,6 +47,9 @@ protected: static void _bind_methods(); void _notification(int p_what); public: + + void set_deploy_dumb(bool p_enabled); + bool is_deploy_dumb_enabled() const; EditorRunNative(); }; diff --git a/tools/editor/fileserver/editor_file_server.cpp b/tools/editor/fileserver/editor_file_server.cpp index f72498f37fb0..f21d9b4ec103 100644 --- a/tools/editor/fileserver/editor_file_server.cpp +++ b/tools/editor/fileserver/editor_file_server.cpp @@ -317,12 +317,33 @@ EditorFileServer::EditorFileServer() { cmd=CMD_NONE; thread=Thread::create(_thread_start,this); + List local_ip; + IP::get_singleton()->get_local_addresses(&local_ip); EDITOR_DEF("file_server/port",6010); + String lip; + String hint; + for(List::Element *E=local_ip.front();E;E=E->next()) { + + String ip = E->get(); + if (ip=="127.0.0.1") + continue; + + if (lip!="") + lip=ip; + if (hint!="") + hint+=","; + hint+=ip; + + } + + EDITOR_DEF("file_server/host",lip); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"file_server/host",PROPERTY_HINT_ENUM,hint)); EDITOR_DEF("file_server/password",""); } EditorFileServer::~EditorFileServer() { + quit=true; Thread::wait_to_finish(thread); memdelete(wait_mutex); diff --git a/tools/editor/icons/icon_animated_sprite_3d.png b/tools/editor/icons/icon_animated_sprite_3d.png new file mode 100644 index 000000000000..19aa7ea2070e Binary files /dev/null and b/tools/editor/icons/icon_animated_sprite_3d.png differ diff --git a/tools/editor/icons/icon_sprite_3d.png b/tools/editor/icons/icon_sprite_3d.png new file mode 100644 index 000000000000..260f7d492054 Binary files /dev/null and b/tools/editor/icons/icon_sprite_3d.png differ diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index f571aba43425..aac3837da9aa 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -449,7 +449,7 @@ Error ProjectExportDialog::export_platform(const String& p_platform, const Strin ERR_PRINT("Invalid platform for export"); return ERR_INVALID_PARAMETER; } - Error err = exporter->export_project(p_path,p_debug,p_password); + Error err = exporter->export_project(p_path,p_debug); if (err!=OK) { error->set_text("Error exporting project!"); error->popup_centered(Size2(300,70));;