mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	-begin work on unidirectional collision detection
-fixed performance issue in new 2D engine -texscreen() working in shader 2D
This commit is contained in:
		
							parent
							
								
									30d3658110
								
							
						
					
					
						commit
						2ef5a342e3
					
				
					 19 changed files with 194 additions and 40 deletions
				
			
		|  | @ -5141,6 +5141,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material | |||
| 
 | ||||
| 		if (p_material->shader_cache->has_texscreen && framebuffer.active) { | ||||
| 			material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); | ||||
| 			material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(0,0,float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); | ||||
| 			material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_TEX,texcoord); | ||||
| 			glActiveTexture(GL_TEXTURE0+texcoord); | ||||
| 			glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); | ||||
|  | @ -8387,11 +8388,32 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { | |||
| 
 | ||||
| 
 | ||||
| 				if (shader->has_texscreen && framebuffer.active) { | ||||
| 
 | ||||
| 					int x = viewport.x; | ||||
| 					int y = window_size.height-(viewport.height+viewport.y); | ||||
| 
 | ||||
| 					canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); | ||||
| 					canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); | ||||
| 					canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,tex_id); | ||||
| 					glActiveTexture(GL_TEXTURE0+tex_id); | ||||
| 					glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); | ||||
| 					if (framebuffer.scale==1 && !canvas_texscreen_used) { | ||||
| #ifdef GLEW_ENABLED | ||||
| 						glReadBuffer(GL_COLOR_ATTACHMENT0); | ||||
| #endif | ||||
| 						glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); | ||||
| 						if (current_clip) { | ||||
| 							print_line(" a clip "); | ||||
| 						} | ||||
| 
 | ||||
| 						canvas_texscreen_used=true; | ||||
| 					} | ||||
| 					tex_id++; | ||||
| 
 | ||||
| 				} | ||||
| 
 | ||||
| 				if (tex_id>1) { | ||||
| 					glActiveTexture(GL_TEXTURE0); | ||||
| 				} | ||||
| 				if (shader->has_screen_uv) { | ||||
| 					canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height)); | ||||
|  | @ -8412,6 +8434,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { | |||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 			canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform); | ||||
| 			canvas_last_shader=shader_owner->shader; | ||||
| 		} | ||||
|  |  | |||
|  | @ -404,7 +404,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a | |||
| 					} else if (callfunc=="texscreen") { | ||||
| 						//create the call to sample the screen, and clamp it
 | ||||
| 						uses_texscreen=true; | ||||
| 						code="(texture2D( texscreen_tex, min(("+dump_node_code(onode->arguments[1],p_level)+").xy*texscreen_screen_mult,texscreen_screen_mult))).rgb"; | ||||
| 						code="(texture2D( texscreen_tex, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy*texscreen_screen_mult,texscreen_screen_clamp.xy,texscreen_screen_clamp.zw))).rgb"; | ||||
| 						//code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb";
 | ||||
| 						break; | ||||
| 					} else if (callfunc=="texpos") { | ||||
|  |  | |||
|  | @ -100,6 +100,7 @@ uniform vec2 screen_uv_mult; | |||
| #if defined(ENABLE_TEXSCREEN) | ||||
| 
 | ||||
| uniform vec2 texscreen_screen_mult; | ||||
| uniform vec4 texscreen_screen_clamp; | ||||
| uniform sampler2D texscreen_tex; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -779,6 +779,7 @@ uniform highp mat4 camera_inverse_transform; | |||
| #if defined(ENABLE_TEXSCREEN) | ||||
| 
 | ||||
| uniform vec2 texscreen_screen_mult; | ||||
| uniform vec4 texscreen_screen_clamp; | ||||
| uniform sampler2D texscreen_tex; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -291,13 +291,27 @@ void Node2D::set_global_transform(const Matrix32& p_transform) { | |||
| 
 | ||||
| void Node2D::set_z(int p_z) { | ||||
| 
 | ||||
| 	ERR_FAIL_COND(p_z<-VS::CANVAS_ITEM_Z_DEFAULT); | ||||
| 	ERR_FAIL_COND(p_z>=VS::CANVAS_ITEM_Z_DEFAULT); | ||||
| 	ERR_FAIL_COND(p_z<VS::CANVAS_ITEM_Z_MIN); | ||||
| 	ERR_FAIL_COND(p_z>VS::CANVAS_ITEM_Z_MAX); | ||||
| 	z=p_z; | ||||
| 	VS::get_singleton()->canvas_item_set_z(get_canvas_item(),z+VS::CANVAS_ITEM_Z_DEFAULT); | ||||
| 	VS::get_singleton()->canvas_item_set_z(get_canvas_item(),z); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void Node2D::set_z_as_relative(bool p_enabled) { | ||||
| 
 | ||||
| 	if (z_relative==p_enabled) | ||||
| 		return; | ||||
| 	z_relative=p_enabled; | ||||
| 	VS::get_singleton()->canvas_item_set_z_as_relative_to_parent(get_canvas_item(),p_enabled); | ||||
| } | ||||
| 
 | ||||
| bool Node2D::is_z_relative() const { | ||||
| 
 | ||||
| 	return z_relative; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int Node2D::get_z() const{ | ||||
| 
 | ||||
| 	return z; | ||||
|  | @ -332,13 +346,16 @@ void Node2D::_bind_methods() { | |||
| 	ObjectTypeDB::bind_method(_MD("set_z","z"),&Node2D::set_z); | ||||
| 	ObjectTypeDB::bind_method(_MD("get_z"),&Node2D::get_z); | ||||
| 
 | ||||
| 	ObjectTypeDB::bind_method(_MD("set_z_as_relative","enable"),&Node2D::set_z_as_relative); | ||||
| 	ObjectTypeDB::bind_method(_MD("is_z_relative"),&Node2D::is_z_relative); | ||||
| 
 | ||||
| 	ObjectTypeDB::bind_method(_MD("edit_set_pivot"),&Node2D::edit_set_pivot); | ||||
| 
 | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos")); | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd")); | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale")); | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::INT,"visibility/z",PROPERTY_HINT_RANGE,"-512,511,1"),_SCS("set_z"),_SCS("get_z")); | ||||
| 
 | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::INT,"z/z",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z"),_SCS("get_z")); | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::BOOL,"z/relative"),_SCS("set_z_as_relative"),_SCS("is_z_relative")); | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -351,6 +368,7 @@ Node2D::Node2D() { | |||
| 	scale=Vector2(1,1); | ||||
| 	_xform_dirty=false; | ||||
| 	z=0; | ||||
| 	z_relative=true; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ class Node2D : public CanvasItem { | |||
| 	float angle; | ||||
| 	Size2 scale; | ||||
| 	int z; | ||||
| 	bool z_relative; | ||||
| 
 | ||||
| 	Matrix32 _mat; | ||||
| 
 | ||||
|  | @ -89,6 +90,8 @@ public: | |||
| 	void set_z(int p_z); | ||||
| 	int get_z() const; | ||||
| 
 | ||||
| 	void set_z_as_relative(bool p_enabled); | ||||
| 	bool is_z_relative() const; | ||||
| 
 | ||||
| 	Matrix32 get_transform() const; | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,13 +43,28 @@ void PhysicsBody2D::_notification(int p_what) { | |||
| 	*/ | ||||
| } | ||||
| 
 | ||||
| void PhysicsBody2D::set_one_way_collision_direction(const Vector2& p_dir) { | ||||
| 
 | ||||
| 	one_way_collision_direction=p_dir; | ||||
| 	Physics2DServer::get_singleton()->body_set_one_way_collision_direction(get_rid(),p_dir); | ||||
| } | ||||
| 
 | ||||
| Vector2 PhysicsBody2D::get_one_way_collision_direction() const{ | ||||
| 
 | ||||
| 	return one_way_collision_direction; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void PhysicsBody2D::_bind_methods() { | ||||
| 
 | ||||
| 	ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); | ||||
| 	ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); | ||||
| 	ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction); | ||||
| 	ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction); | ||||
| 	ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with); | ||||
| 	ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with); | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); | ||||
| 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction")); | ||||
| } | ||||
| 
 | ||||
| void PhysicsBody2D::set_layer_mask(uint32_t p_mask) { | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ class PhysicsBody2D : public CollisionObject2D { | |||
| 	OBJ_TYPE(PhysicsBody2D,CollisionObject2D); | ||||
| 
 | ||||
| 	uint32_t mask; | ||||
| 	Vector2 one_way_collision_direction; | ||||
| protected: | ||||
| 
 | ||||
| 	void _notification(int p_what); | ||||
|  | @ -53,6 +54,9 @@ public: | |||
| 	void add_collision_exception_with(Node* p_node); //must be physicsbody
 | ||||
| 	void remove_collision_exception_with(Node* p_node); | ||||
| 
 | ||||
| 	void set_one_way_collision_direction(const Vector2& p_dir); | ||||
| 	Vector2 get_one_way_collision_direction() const; | ||||
| 
 | ||||
| 	PhysicsBody2D(); | ||||
| 
 | ||||
| }; | ||||
|  |  | |||
|  | @ -92,6 +92,7 @@ void PhysicsBody::remove_collision_exception_with(Node* p_node) { | |||
| 	PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(),physics_body->get_rid()); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void PhysicsBody::_bind_methods() { | ||||
| 	ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody::set_layer_mask); | ||||
| 	ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody::get_layer_mask); | ||||
|  |  | |||
|  | @ -56,6 +56,8 @@ public: | |||
| 	void add_collision_exception_with(Node* p_node); //must be physicsbody
 | ||||
| 	void remove_collision_exception_with(Node* p_node); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	PhysicsBody(); | ||||
| 
 | ||||
| }; | ||||
|  |  | |||
|  | @ -67,6 +67,8 @@ class Body2DSW : public CollisionObject2DSW { | |||
| 	Vector2 applied_force; | ||||
| 	real_t applied_torque; | ||||
| 
 | ||||
| 	Vector2 one_way_collision_direction; | ||||
| 
 | ||||
| 
 | ||||
| 	SelfList<Body2DSW> active_list; | ||||
| 	SelfList<Body2DSW> inertia_update_list; | ||||
|  | @ -216,6 +218,9 @@ public: | |||
| 	_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode=p_mode; } | ||||
| 	_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; } | ||||
| 
 | ||||
| 	void set_one_way_collision_direction(const Vector2& p_dir) { one_way_collision_direction=p_dir; } | ||||
| 	Vector2 get_one_way_collision_direction() const { return one_way_collision_direction; } | ||||
| 
 | ||||
| 	void set_space(Space2DSW *p_space); | ||||
| 
 | ||||
| 	void update_inertias(); | ||||
|  |  | |||
|  | @ -860,6 +860,22 @@ int Physics2DServerSW::body_get_max_contacts_reported(RID p_body) const { | |||
| 	return body->get_max_contacts_reported(); | ||||
| } | ||||
| 
 | ||||
| void Physics2DServerSW::body_set_one_way_collision_direction(RID p_body,const Vector2& p_direction) { | ||||
| 
 | ||||
| 	Body2DSW *body = body_owner.get(p_body); | ||||
| 	ERR_FAIL_COND(!body); | ||||
| 	body->set_one_way_collision_direction(p_direction); | ||||
| } | ||||
| 
 | ||||
| Vector2 Physics2DServerSW::body_get_one_way_collision_direction(RID p_body) const{ | ||||
| 
 | ||||
| 	Body2DSW *body = body_owner.get(p_body); | ||||
| 	ERR_FAIL_COND_V(!body,Vector2()); | ||||
| 	return body->get_one_way_collision_direction(); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void Physics2DServerSW::body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata) { | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -205,6 +205,9 @@ public: | |||
| 	virtual void body_set_max_contacts_reported(RID p_body, int p_contacts); | ||||
| 	virtual int body_get_max_contacts_reported(RID p_body) const; | ||||
| 
 | ||||
| 	virtual void body_set_one_way_collision_direction(RID p_body,const Vector2& p_direction); | ||||
| 	virtual Vector2 body_get_one_way_collision_direction(RID p_body) const; | ||||
| 
 | ||||
| 	virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant()); | ||||
| 	virtual bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count); | ||||
| 
 | ||||
|  |  | |||
|  | @ -500,6 +500,10 @@ void Physics2DServer::_bind_methods() { | |||
| 	ObjectTypeDB::bind_method(_MD("body_set_max_contacts_reported","body","amount"),&Physics2DServer::body_set_max_contacts_reported); | ||||
| 	ObjectTypeDB::bind_method(_MD("body_get_max_contacts_reported","body"),&Physics2DServer::body_get_max_contacts_reported); | ||||
| 
 | ||||
| 	ObjectTypeDB::bind_method(_MD("body_set_one_way_collision_direction","normal"),&Physics2DServer::body_set_one_way_collision_direction); | ||||
| 	ObjectTypeDB::bind_method(_MD("body_get_one_way_collision_direction"),&Physics2DServer::body_get_one_way_collision_direction); | ||||
| 
 | ||||
| 
 | ||||
| 	ObjectTypeDB::bind_method(_MD("body_set_omit_force_integration","body","enable"),&Physics2DServer::body_set_omit_force_integration); | ||||
| 	ObjectTypeDB::bind_method(_MD("body_is_omitting_force_integration","body"),&Physics2DServer::body_is_omitting_force_integration); | ||||
| 
 | ||||
|  |  | |||
|  | @ -442,6 +442,9 @@ public: | |||
| 	virtual void body_set_max_contacts_reported(RID p_body, int p_contacts)=0; | ||||
| 	virtual int body_get_max_contacts_reported(RID p_body) const=0; | ||||
| 
 | ||||
| 	virtual void body_set_one_way_collision_direction(RID p_body,const Vector2& p_direction)=0; | ||||
| 	virtual Vector2 body_get_one_way_collision_direction(RID p_body) const=0; | ||||
| 
 | ||||
| 	//missing remove
 | ||||
| 	virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold)=0; | ||||
| 	virtual float body_get_contacts_reported_depth_treshold(RID p_body) const=0; | ||||
|  |  | |||
|  | @ -3691,7 +3691,7 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen | |||
| 
 | ||||
| void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) { | ||||
| 
 | ||||
| 	ERR_FAIL_COND(p_z<0 || p_z>=CANVAS_ITEM_Z_MAX); | ||||
| 	ERR_FAIL_COND(p_z<CANVAS_ITEM_Z_MIN || p_z>CANVAS_ITEM_Z_MAX); | ||||
| 	VS_CHANGED; | ||||
| 	CanvasItem *canvas_item = canvas_item_owner.get( p_item ); | ||||
| 	ERR_FAIL_COND(!canvas_item); | ||||
|  | @ -3699,6 +3699,15 @@ void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) { | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) { | ||||
| 
 | ||||
| 	VS_CHANGED; | ||||
| 	CanvasItem *canvas_item = canvas_item_owner.get( p_item ); | ||||
| 	ERR_FAIL_COND(!canvas_item); | ||||
| 	canvas_item->z_relative=p_enable; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) { | ||||
| 
 | ||||
| 	VS_CHANGED; | ||||
|  | @ -6139,18 +6148,20 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S | |||
| 
 | ||||
| void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) { | ||||
| 
 | ||||
| 	Rasterizer::CanvasItem *z_list[CANVAS_ITEM_Z_MAX]; | ||||
| 	Rasterizer::CanvasItem *z_last_list[CANVAS_ITEM_Z_MAX]; | ||||
| 
 | ||||
| 	for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) { | ||||
| 	static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1; | ||||
| 	Rasterizer::CanvasItem *z_list[z_range]; | ||||
| 	Rasterizer::CanvasItem *z_last_list[z_range]; | ||||
| 
 | ||||
| 	for(int i=0;i<z_range;i++) { | ||||
| 		z_list[i]=NULL; | ||||
| 		z_last_list[i]=NULL; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	_render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,z_list,z_last_list,NULL,NULL); | ||||
| 	_render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,0,z_list,z_last_list,NULL,NULL); | ||||
| 
 | ||||
| 	for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) { | ||||
| 	for(int i=0;i<z_range;i++) { | ||||
| 		if (!z_list[i]) | ||||
| 			continue; | ||||
| 		rasterizer->canvas_render_items(z_list[i]); | ||||
|  | @ -6168,7 +6179,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) { | ||||
| void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) { | ||||
| 
 | ||||
| 	CanvasItem *ci = p_canvas_item; | ||||
| 
 | ||||
|  | @ -6247,7 +6258,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat | |||
| 
 | ||||
| 		if (child_items[i]->ontop) | ||||
| 			continue; | ||||
| 		_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); | ||||
| 		_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
|  | @ -6256,13 +6267,20 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat | |||
| 		ci->final_transform=xform; | ||||
| 		ci->final_opacity=opacity * ci->self_opacity; | ||||
| 
 | ||||
| 		if (z_last_list[ci->z]) { | ||||
| 			z_last_list[ci->z]->next=ci; | ||||
| 			z_last_list[ci->z]=ci; | ||||
| 		if (ci->z_relative) | ||||
| 			p_z=CLAMP(p_z+ci->z,CANVAS_ITEM_Z_MIN,CANVAS_ITEM_Z_MAX); | ||||
| 		else | ||||
| 			p_z=ci->z; | ||||
| 
 | ||||
| 		int zidx = p_z-CANVAS_ITEM_Z_MIN; | ||||
| 
 | ||||
| 		if (z_last_list[zidx]) { | ||||
| 			z_last_list[zidx]->next=ci; | ||||
| 			z_last_list[zidx]=ci; | ||||
| 
 | ||||
| 		} else { | ||||
| 			z_list[ci->z]=ci; | ||||
| 			z_last_list[ci->z]=ci; | ||||
| 			z_list[zidx]=ci; | ||||
| 			z_last_list[zidx]=ci; | ||||
| 		} | ||||
| 
 | ||||
| 		ci->next=NULL; | ||||
|  | @ -6273,7 +6291,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat | |||
| 
 | ||||
| 		if (!child_items[i]->ontop) | ||||
| 			continue; | ||||
| 		_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); | ||||
| 		_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -6282,31 +6300,62 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans | |||
| 
 | ||||
| 	rasterizer->canvas_begin(); | ||||
| 
 | ||||
| 
 | ||||
| 	int l = p_canvas->child_items.size(); | ||||
| 	Canvas::ChildItem *ci=p_canvas->child_items.ptr(); | ||||
| 
 | ||||
| 	bool has_mirror=false; | ||||
| 	for(int i=0;i<l;i++) { | ||||
| 
 | ||||
| 		Canvas::ChildItem& ci=p_canvas->child_items[i]; | ||||
| 		_render_canvas_item_tree(ci.item,p_transform,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height)); | ||||
| 
 | ||||
| 		//mirroring (useful for scrolling backgrounds)
 | ||||
| 		if (ci.mirror.x!=0) { | ||||
| 
 | ||||
| 			Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0)); | ||||
| 			_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height)); | ||||
| 		if (ci[i].mirror.x || ci[i].mirror.y) { | ||||
| 			has_mirror=true; | ||||
| 			break; | ||||
| 		} | ||||
| 		if (ci.mirror.y!=0) { | ||||
| 	} | ||||
| 
 | ||||
| 			Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y)); | ||||
| 			_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height)); | ||||
| 	Rect2 clip_rect(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height); | ||||
| 	if (!has_mirror) { | ||||
| 
 | ||||
| 		static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1; | ||||
| 		Rasterizer::CanvasItem *z_list[z_range]; | ||||
| 		Rasterizer::CanvasItem *z_last_list[z_range]; | ||||
| 
 | ||||
| 		for(int i=0;i<z_range;i++) { | ||||
| 			z_list[i]=NULL; | ||||
| 			z_last_list[i]=NULL; | ||||
| 		} | ||||
| 		if (ci.mirror.y!=0 && ci.mirror.x!=0) { | ||||
| 
 | ||||
| 			Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror); | ||||
| 			_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height)); | ||||
| 		for(int i=0;i<l;i++) { | ||||
| 			_render_canvas_item(ci[i].item,p_transform,clip_rect,1.0,0,z_list,z_last_list,NULL,NULL); | ||||
| 		} | ||||
| 
 | ||||
| 		for(int i=0;i<z_range;i++) { | ||||
| 			if (!z_list[i]) | ||||
| 				continue; | ||||
| 			rasterizer->canvas_render_items(z_list[i]); | ||||
| 		} | ||||
| 	} else { | ||||
| 
 | ||||
| 		for(int i=0;i<l;i++) { | ||||
| 
 | ||||
| 			Canvas::ChildItem& ci=p_canvas->child_items[i]; | ||||
| 			_render_canvas_item_tree(ci.item,p_transform,clip_rect); | ||||
| 
 | ||||
| 			//mirroring (useful for scrolling backgrounds)
 | ||||
| 			if (ci.mirror.x!=0) { | ||||
| 
 | ||||
| 				Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0)); | ||||
| 				_render_canvas_item_tree(ci.item,xform2,clip_rect); | ||||
| 			} | ||||
| 			if (ci.mirror.y!=0) { | ||||
| 
 | ||||
| 				Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y)); | ||||
| 				_render_canvas_item_tree(ci.item,xform2,clip_rect); | ||||
| 			} | ||||
| 			if (ci.mirror.y!=0 && ci.mirror.x!=0) { | ||||
| 
 | ||||
| 				Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror); | ||||
| 				_render_canvas_item_tree(ci.item,xform2,clip_rect); | ||||
| 			} | ||||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -380,6 +380,7 @@ class VisualServerRaster : public VisualServer { | |||
| 		List<CanvasItem*>::Element *E; | ||||
| 		RID viewport; | ||||
| 		int z; | ||||
| 		bool z_relative; | ||||
| 		bool sort_y; | ||||
| 		float opacity; | ||||
| 		float self_opacity; | ||||
|  | @ -396,6 +397,7 @@ class VisualServerRaster : public VisualServer { | |||
| 			self_opacity=1; | ||||
| 			sort_y=false; | ||||
| 			use_parent_shader=false; | ||||
| 			z_relative=true; | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -600,7 +602,7 @@ class VisualServerRaster : public VisualServer { | |||
| 	void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); | ||||
| 	static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); | ||||
| 	void _render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect); | ||||
| 	void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect,float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner); | ||||
| 	void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner); | ||||
| 	void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform); | ||||
| 	Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); | ||||
| 	Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); | ||||
|  | @ -1112,6 +1114,7 @@ public: | |||
| 	virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore); | ||||
| 	virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable); | ||||
| 	virtual void canvas_item_set_z(RID p_item, int p_z); | ||||
| 	virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable); | ||||
| 
 | ||||
| 	virtual void canvas_item_set_shader(RID p_item, RID p_shader); | ||||
| 	virtual RID canvas_item_get_shader(RID p_item) const; | ||||
|  |  | |||
|  | @ -1132,6 +1132,7 @@ public: | |||
| 
 | ||||
| 	FUNC2(canvas_item_set_sort_children_by_y,RID,bool); | ||||
| 	FUNC2(canvas_item_set_z,RID,int); | ||||
| 	FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool); | ||||
| 
 | ||||
| 	FUNC2(canvas_item_set_shader,RID, RID ); | ||||
| 	FUNC1RC(RID,canvas_item_get_shader,RID ); | ||||
|  |  | |||
|  | @ -86,8 +86,9 @@ public: | |||
| 		ARRAY_WEIGHTS_SIZE=4, | ||||
| 		MAX_PARTICLE_COLOR_PHASES=4, | ||||
| 		MAX_PARTICLE_ATTRACTORS=4, | ||||
| 		CANVAS_ITEM_Z_MAX=1024, | ||||
| 		CANVAS_ITEM_Z_DEFAULT=512, | ||||
| 		CANVAS_ITEM_Z_MIN=-4096, | ||||
| 		CANVAS_ITEM_Z_MAX=4096, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		MAX_CURSORS = 8, | ||||
|  | @ -985,6 +986,7 @@ public: | |||
| 	virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore)=0; | ||||
| 	virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable)=0; | ||||
| 	virtual void canvas_item_set_z(RID p_item, int p_z)=0; | ||||
| 	virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable)=0; | ||||
| 
 | ||||
| 	virtual void canvas_item_clear(RID p_item)=0; | ||||
| 	virtual void canvas_item_raise(RID p_item)=0; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Juan Linietsky
						Juan Linietsky