summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/immediate_geometry.cpp102
-rw-r--r--scene/3d/immediate_geometry.h41
-rw-r--r--scene/3d/sprite_3d.cpp772
-rw-r--r--scene/3d/sprite_3d.h191
-rw-r--r--scene/gui/label.cpp11
-rw-r--r--scene/register_scene_types.cpp5
-rw-r--r--scene/resources/environment.cpp15
-rw-r--r--scene/resources/environment.h10
-rw-r--r--scene/resources/material.cpp9
-rw-r--r--scene/resources/material.h2
-rw-r--r--scene/resources/texture.cpp43
-rw-r--r--scene/resources/texture.h2
-rw-r--r--scene/scene_string_names.cpp2
-rw-r--r--scene/scene_string_names.h4
14 files changed, 1204 insertions, 5 deletions
diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp
new file mode 100644
index 0000000000..1459f2c362
--- /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<Texture>& 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<Face3> ImmediateGeometry::get_faces(uint32_t p_usage_flags) const {
+
+ return DVector<Face3>();
+}
+
+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 0000000000..2db81134c6
--- /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<Ref<Texture> > cached_textures;
+ bool empty;
+ AABB aabb;
+protected:
+
+ static void _bind_methods();
+public:
+
+
+ void begin(Mesh::PrimitiveType p_primitive,const Ref<Texture>& 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<Face3> 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 0000000000..21fdb9abd3
--- /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<SpriteBase3D*>::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<SpriteBase3D>();
+ 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<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const {
+
+ return DVector<Face3>();
+
+}
+
+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<Texture>& 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<Texture> 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> 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<SpriteFrames>& 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<SpriteFrames> 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<Texture> 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 0000000000..1330cd1c30
--- /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<SpriteBase3D*> children;
+ List<SpriteBase3D*>::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<Face3> get_faces(uint32_t p_usage_flags) const;
+
+ SpriteBase3D();
+ ~SpriteBase3D();
+};
+
+
+class Sprite3D : public SpriteBase3D {
+
+ OBJ_TYPE(Sprite3D,SpriteBase3D);
+ Ref<Texture> 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<Texture>& p_texture);
+ Ref<Texture> 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<SpriteFrames> frames;
+
+
+ int frame;
+
+protected:
+ virtual void _draw();
+ static void _bind_methods();
+public:
+
+
+
+ void set_sprite_frames(const Ref<SpriteFrames>& p_sprite_frames);
+ Ref<SpriteFrames> 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/gui/label.cpp b/scene/gui/label.cpp
index a2f837c3c4..b7918994d8 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -398,12 +398,15 @@ void Label::regenerate_word_cache() {
}
if (current=='\n') {
-
insert_newline=true;
} else {
total_char_cache++;
}
+ if (i<text.length() && text[i] == ' ') {
+ total_char_cache--; // do not count spaces
+ }
+
} else {
@@ -442,7 +445,8 @@ void Label::regenerate_word_cache() {
last_width=line_width;
}
-
+
+ total_char_cache -= line_count + 1; // do not count new lines (including the first one)
if (!autowrap) {
@@ -519,6 +523,7 @@ String Label::get_text() const {
return text;
}
+
void Label::set_visible_characters(int p_amount) {
visible_chars=p_amount;
@@ -582,7 +587,7 @@ void Label::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::INT, "valign", PROPERTY_HINT_ENUM,"Top,Center,Bottom,Fill" ),_SCS("set_valign"),_SCS("get_valign") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "autowrap"),_SCS("set_autowrap"),_SCS("has_autowrap") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "uppercase"),_SCS("set_uppercase"),_SCS("is_uppercase") );
- ADD_PROPERTY( PropertyInfo( Variant::REAL, "percent_visible"),_SCS("set_percent_visible"),_SCS("get_percent_visible") );
+ ADD_PROPERTY( PropertyInfo( Variant::REAL, "percent_visible", PROPERTY_HINT_RANGE,"0,1,0.001"),_SCS("set_percent_visible"),_SCS("get_percent_visible") );
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index b30ad2d71f..f3d757b601 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<InterpolatedCamera>();
ObjectTypeDB::register_type<TestCube>();
ObjectTypeDB::register_type<MeshInstance>();
+ ObjectTypeDB::register_type<ImmediateGeometry>();
+ ObjectTypeDB::register_type<Sprite3D>();
+ ObjectTypeDB::register_type<AnimatedSprite3D>();
ObjectTypeDB::register_virtual_type<Light>();
ObjectTypeDB::register_type<DirectionalLight>();
ObjectTypeDB::register_type<OmniLight>();
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 0c55d22dbe..99447c0a0e 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<CubeMap>());
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;i<FX_MAX;i++)
set_enable_fx(Fx(i),false);
fx_set_param(FX_PARAM_GLOW_BLUR_PASSES,1);
+ fx_set_param(FX_PARAM_GLOW_BLUR_SCALE,1);
+ fx_set_param(FX_PARAM_GLOW_BLUR_STRENGTH,1);
fx_set_param(FX_PARAM_GLOW_BLOOM,0.0);
fx_set_param(FX_PARAM_GLOW_BLOOM_TRESHOLD,0.5);
fx_set_param(FX_PARAM_DOF_BLUR_PASSES,1);
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index b90a043634..627fbb7cc0 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -56,6 +56,7 @@ public:
BG_PARAM_CUBEMAP=VS::ENV_BG_PARAM_CUBEMAP,
BG_PARAM_ENERGY=VS::ENV_BG_PARAM_ENERGY,
BG_PARAM_SCALE=VS::ENV_BG_PARAM_SCALE,
+ BG_PARAM_GLOW=VS::ENV_BG_PARAM_GLOW,
BG_PARAM_MAX=VS::ENV_BG_PARAM_MAX
};
@@ -70,8 +71,17 @@ public:
FX_MAX=VS::ENV_FX_MAX,
};
+ enum FxBlurBlendMode {
+ FX_BLUR_BLEND_MODE_ADDITIVE,
+ FX_BLUR_BLEND_MODE_SCREEN,
+ FX_BLUR_BLEND_MODE_SOFTLIGHT,
+ };
+
enum FxParam {
FX_PARAM_GLOW_BLUR_PASSES=VS::ENV_FX_PARAM_GLOW_BLUR_PASSES,
+ FX_PARAM_GLOW_BLUR_SCALE=VS::ENV_FX_PARAM_GLOW_BLUR_SCALE,
+ FX_PARAM_GLOW_BLUR_STRENGTH=VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH,
+ FX_PARAM_GLOW_BLUR_BLEND_MODE=VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE,
FX_PARAM_GLOW_BLOOM=VS::ENV_FX_PARAM_GLOW_BLOOM,
FX_PARAM_GLOW_BLOOM_TRESHOLD=VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD,
FX_PARAM_DOF_BLUR_PASSES=VS::ENV_FX_PARAM_DOF_BLUR_PASSES,
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 2ddfa1078b..091a46d4ab 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -45,6 +45,7 @@ static const char*_hint_names[Material::HINT_MAX]={
"opaque_pre_zpass",
"no_shadow",
"no_depth_draw",
+ "no_alpha_depth_draw",
};
static const Material::Flag _flag_indices[Material::FLAG_MAX]={
@@ -175,6 +176,7 @@ void Material::_bind_methods() {
BIND_CONSTANT( HINT_OPAQUE_PRE_PASS );
BIND_CONSTANT( HINT_NO_SHADOW );
BIND_CONSTANT( HINT_NO_DEPTH_DRAW );
+ BIND_CONSTANT( HINT_NO_DEPTH_DRAW_FOR_ALPHA );
BIND_CONSTANT( HINT_MAX );
BIND_CONSTANT( SHADE_MODEL_LAMBERT );
@@ -208,6 +210,7 @@ Material::Material(const RID& p_material) {
for(int i=0;i<HINT_MAX;i++)
hints[i]=false;
+ hints[HINT_NO_DEPTH_DRAW_FOR_ALPHA]=true;
blend_mode=BLEND_MODE_MIX;
shade_model = SHADE_MODEL_LAMBERT;
@@ -365,14 +368,14 @@ Material::BlendMode FixedMaterial::get_detail_blend_mode() const {
}
void FixedMaterial::set_fixed_flag(FixedFlag p_flag, bool p_value) {
- ERR_FAIL_INDEX(p_flag,3);
+ ERR_FAIL_INDEX(p_flag,4);
fixed_flags[p_flag]=p_value;
VisualServer::get_singleton()->fixed_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 1f2afb70b9..2057b3cac9 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 5402a28d92..5b31ba1f1b 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 b780d70e1a..86ff246498 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 5c54bd74e3..a8e4c80f89 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 6a4e58ed54..2286712250 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;
+
+
};