Browse Source

-Initial working(?) implementation of shaders for 2D. Lighting still not there though.

Check for reference:
https://github.com/okamstudio/godot/wiki/shader
Juan Linietsky 10 years ago
parent
commit
544ce2a1db

+ 35 - 3
drivers/gles2/rasterizer_gles2.cpp

@@ -1564,6 +1564,7 @@ void RasterizerGLES2::shader_set_default_texture_param(RID p_shader, const Strin
 
 
 RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
 RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName& p_name) const{
 	const Shader *shader=shader_owner.get(p_shader);
 	const Shader *shader=shader_owner.get(p_shader);
+	ERR_FAIL_COND_V(!shader,RID());
 
 
 	const Map<StringName,RID>::Element *E=shader->default_textures.find(p_name);
 	const Map<StringName,RID>::Element *E=shader->default_textures.find(p_name);
 	if (!E)
 	if (!E)
@@ -1571,6 +1572,22 @@ RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const String
 	return E->get();
 	return E->get();
 }
 }
 
 
+Variant RasterizerGLES2::shader_get_default_param(RID p_shader, const StringName& p_name) {
+
+	Shader *shader=shader_owner.get(p_shader);
+	ERR_FAIL_COND_V(!shader,Variant());
+
+	//update shader params if necesary
+	//make sure the shader is compiled and everything
+	//so the actual parameters can be properly retrieved!
+	if (shader->dirty_list.in_list()) {
+		_update_shader(shader);
+	}
+	if (shader->valid && shader->uniforms.has(p_name))
+		return shader->uniforms[p_name].default_value;
+
+	return Variant();
+}
 
 
 
 
 /* COMMON MATERIAL API */
 /* COMMON MATERIAL API */
@@ -4567,6 +4584,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 		if (fragment_flags.uses_screen_uv) {
 		if (fragment_flags.uses_screen_uv) {
 			enablers.push_back("#define ENABLE_SCREEN_UV\n");
 			enablers.push_back("#define ENABLE_SCREEN_UV\n");
 		}
 		}
+		if (fragment_flags.uses_texpixel_size) {
+			enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
+		}
 
 
 		canvas_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers);
 		canvas_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, light_code, fragment_globals,uniform_names,enablers);
 
 
@@ -4582,6 +4602,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
 	p_shader->can_zpass=!fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex;
 	p_shader->can_zpass=!fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex;
 	p_shader->uses_normal=fragment_flags.uses_normal || light_flags.uses_normal;
 	p_shader->uses_normal=fragment_flags.uses_normal || light_flags.uses_normal;
 	p_shader->uses_time=uses_time;
 	p_shader->uses_time=uses_time;
+	p_shader->uses_texpixel_size=fragment_flags.uses_texpixel_size;
 	p_shader->version++;
 	p_shader->version++;
 
 
 }
 }
@@ -7874,7 +7895,7 @@ void RasterizerGLES2::canvas_end_rect() {
 
 
 RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_texture) {
 RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_texture) {
 
 
-	if (p_texture==canvas_tex) {
+	if (p_texture==canvas_tex && !rebind_texpixel_size) {
 		if (canvas_tex.is_valid()) {
 		if (canvas_tex.is_valid()) {
 			Texture*texture=texture_owner.get(p_texture);
 			Texture*texture=texture_owner.get(p_texture);
 			return texture;
 			return texture;
@@ -7882,14 +7903,16 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex
 		return NULL;
 		return NULL;
 	}
 	}
 
 
-
+	rebind_texpixel_size=false;
 
 
 	if (p_texture.is_valid()) {
 	if (p_texture.is_valid()) {
 
 
+
 		Texture*texture=texture_owner.get(p_texture);
 		Texture*texture=texture_owner.get(p_texture);
 		if (!texture) {
 		if (!texture) {
 			canvas_tex=RID();
 			canvas_tex=RID();
 			glBindTexture(GL_TEXTURE_2D,white_tex);
 			glBindTexture(GL_TEXTURE_2D,white_tex);
+
 			return NULL;
 			return NULL;
 		}
 		}
 
 
@@ -7898,6 +7921,9 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex
 
 
 		glBindTexture(GL_TEXTURE_2D,texture->tex_id);
 		glBindTexture(GL_TEXTURE_2D,texture->tex_id);
 		canvas_tex=p_texture;
 		canvas_tex=p_texture;
+		if (uses_texpixel_size) {
+			canvas_shader.set_uniform(CanvasShaderGLES2::TEXPIXEL_SIZE,Size2(1.0/texture->width,1.0/texture->height));
+		}
 		return texture;
 		return texture;
 
 
 
 
@@ -8281,6 +8307,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 		csy = -1.0;
 		csy = -1.0;
 
 
 	canvas_transform.scale( Vector3( 2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f ) );
 	canvas_transform.scale( Vector3( 2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f ) );
+	canvas_opacity=1.0;
+	uses_texpixel_size=false;
 
 
 
 
 	canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
 	canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
@@ -8330,7 +8358,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 
 
 			if (shader) {
 			if (shader) {
 				canvas_shader.set_custom_shader(shader->custom_code_id);
 				canvas_shader.set_custom_shader(shader->custom_code_id);
-				canvas_shader.bind();
+				if (canvas_shader.bind())
+					rebind_texpixel_size=true;
 
 
 				if (ci->shader_version!=shader->version) {
 				if (ci->shader_version!=shader->version) {
 					//todo optimize uniforms
 					//todo optimize uniforms
@@ -8383,9 +8412,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
 				}
 				}
 					//if uses TIME - draw_next_frame=true
 					//if uses TIME - draw_next_frame=true
 
 
+				uses_texpixel_size=shader->uses_texpixel_size;
+
 			} else {
 			} else {
 				canvas_shader.set_custom_shader(0);
 				canvas_shader.set_custom_shader(0);
 				canvas_shader.bind();
 				canvas_shader.bind();
+				uses_texpixel_size=false;
 
 
 			}
 			}
 
 

+ 5 - 0
drivers/gles2/rasterizer_gles2.h

@@ -192,6 +192,7 @@ class RasterizerGLES2 : public Rasterizer {
 		bool uses_discard;
 		bool uses_discard;
 		bool uses_time;
 		bool uses_time;
 		bool uses_normal;
 		bool uses_normal;
+		bool uses_texpixel_size;
 
 
 		Map<StringName,ShaderLanguage::Uniform> uniforms;
 		Map<StringName,ShaderLanguage::Uniform> uniforms;
 		StringName first_texture;
 		StringName first_texture;
@@ -1171,6 +1172,8 @@ class RasterizerGLES2 : public Rasterizer {
 	GLuint white_tex;
 	GLuint white_tex;
 	RID canvas_tex;
 	RID canvas_tex;
 	float canvas_opacity;
 	float canvas_opacity;
+	bool uses_texpixel_size;
+	bool rebind_texpixel_size;
 	_FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture);
 	_FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture);
 	VS::MaterialBlendMode canvas_blend_mode;
 	VS::MaterialBlendMode canvas_blend_mode;
 
 
@@ -1262,6 +1265,8 @@ public:
 	virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
 	virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
 	virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
 	virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
 
 
+	virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name);
+
 	/* COMMON MATERIAL API */
 	/* COMMON MATERIAL API */
 
 
 	virtual RID material_create();
 	virtual RID material_create();

+ 51 - 3
drivers/gles2/shader_compiler_gles2.cpp

@@ -147,6 +147,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 		} break;
 		} break;
 		case SL::Node::TYPE_VARIABLE: {
 		case SL::Node::TYPE_VARIABLE: {
 			SL::VariableNode *vnode=(SL::VariableNode*)p_node;
 			SL::VariableNode *vnode=(SL::VariableNode*)p_node;
+
 			if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) {
 			if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) {
 
 
 				if (vnode->name==vname_vertex && p_assign_left) {
 				if (vnode->name==vname_vertex && p_assign_left) {
@@ -173,6 +174,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 
 
 
 
 			}
 			}
+
+
+
 			if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) {
 			if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) {
 
 
 				if (vnode->name==vname_discard) {
 				if (vnode->name==vname_discard) {
@@ -181,9 +185,6 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 				if (vnode->name==vname_normalmap) {
 				if (vnode->name==vname_normalmap) {
 					uses_normalmap=true;
 					uses_normalmap=true;
 				}
 				}
-				if (vnode->name==vname_normal) {
-					uses_normal=true;
-				}
 				if (vnode->name==vname_screen_uv) {
 				if (vnode->name==vname_screen_uv) {
 					uses_screen_uv=true;
 					uses_screen_uv=true;
 				}
 				}
@@ -216,6 +217,47 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
 					uses_light=true;
 					uses_light=true;
 				}
 				}
 
 
+			}
+			if (type==ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX) {
+
+				if (vnode->name==vname_var1_interp) {
+					flags->use_var1_interp=true;
+				}
+				if (vnode->name==vname_var2_interp) {
+					flags->use_var2_interp=true;
+				}
+
+			}
+
+
+			if (type==ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT) {
+
+
+				if (vnode->name==vname_texpixel_size) {
+					uses_texpixel_size=true;
+				}
+				if (vnode->name==vname_normal) {
+					uses_normal=true;
+				}
+
+				if (vnode->name==vname_screen_uv) {
+					uses_screen_uv=true;
+				}
+
+				if (vnode->name==vname_var1_interp) {
+					flags->use_var1_interp=true;
+				}
+				if (vnode->name==vname_var2_interp) {
+					flags->use_var2_interp=true;
+				}
+			}
+
+			if (type==ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT) {
+
+				if (vnode->name==vname_light) {
+					uses_light=true;
+				}
+
 			}
 			}
 
 
 			if (vnode->name==vname_time) {
 			if (vnode->name==vname_time) {
@@ -556,6 +598,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	uses_time=false;
 	uses_time=false;
 	uses_normalmap=false;
 	uses_normalmap=false;
 	uses_normal=false;
 	uses_normal=false;
+	uses_texpixel_size=false;
 	vertex_code_writes_vertex=false;
 	vertex_code_writes_vertex=false;
 	uniforms=r_uniforms;
 	uniforms=r_uniforms;
 	flags=&r_flags;
 	flags=&r_flags;
@@ -590,6 +633,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
 	r_flags.uses_time=uses_time;
 	r_flags.uses_time=uses_time;
 	r_flags.uses_normalmap=uses_normalmap;
 	r_flags.uses_normalmap=uses_normalmap;
 	r_flags.uses_normal=uses_normalmap;
 	r_flags.uses_normal=uses_normalmap;
+	r_flags.uses_texpixel_size=uses_texpixel_size;
 	r_code_line=code;
 	r_code_line=code;
 	r_globals_line=global_code;
 	r_globals_line=global_code;
 
 
@@ -742,14 +786,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	mode_replace_table[4]["POSITION"]="gl_Position";
 	mode_replace_table[4]["POSITION"]="gl_Position";
 	mode_replace_table[4]["NORMAL"]="normal";
 	mode_replace_table[4]["NORMAL"]="normal";
 	mode_replace_table[4]["UV"]="uv_interp";
 	mode_replace_table[4]["UV"]="uv_interp";
+	mode_replace_table[4]["SRC_COLOR"]="color_interp";
 	mode_replace_table[4]["COLOR"]="color";
 	mode_replace_table[4]["COLOR"]="color";
 	mode_replace_table[4]["TEXTURE"]="texture";
 	mode_replace_table[4]["TEXTURE"]="texture";
+	mode_replace_table[4]["TEXTURE_PIXEL_SIZE"]="texpixel_size";
 	mode_replace_table[4]["VAR1"]="var1_interp";
 	mode_replace_table[4]["VAR1"]="var1_interp";
 	mode_replace_table[4]["VAR2"]="var2_interp";
 	mode_replace_table[4]["VAR2"]="var2_interp";
 	mode_replace_table[4]["SCREEN_UV"]="screen_uv";
 	mode_replace_table[4]["SCREEN_UV"]="screen_uv";
 	mode_replace_table[4]["POINT_COORD"]="gl_PointCoord";
 	mode_replace_table[4]["POINT_COORD"]="gl_PointCoord";
 	mode_replace_table[4]["TIME"]="time";
 	mode_replace_table[4]["TIME"]="time";
 
 
+	mode_replace_table[5]["SRC_COLOR"]="color";
 	mode_replace_table[5]["COLOR"]="color";
 	mode_replace_table[5]["COLOR"]="color";
 	mode_replace_table[5]["NORMAL"]="normal";
 	mode_replace_table[5]["NORMAL"]="normal";
 	mode_replace_table[5]["LIGHT_DIR"]="light_dir";
 	mode_replace_table[5]["LIGHT_DIR"]="light_dir";
@@ -781,5 +828,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	vname_time="TIME";
 	vname_time="TIME";
 	vname_normalmap="NORMALMAP";
 	vname_normalmap="NORMALMAP";
 	vname_normal="NORMAL";
 	vname_normal="NORMAL";
+	vname_texpixel_size="TEXTURE_PIXEL_SIZE";
 
 
 }
 }

+ 3 - 0
drivers/gles2/shader_compiler_gles2.h

@@ -52,6 +52,7 @@ private:
 	bool uses_screen_uv;
 	bool uses_screen_uv;
 	bool uses_normalmap;
 	bool uses_normalmap;
 	bool uses_normal;
 	bool uses_normal;
+	bool uses_texpixel_size;
 	bool vertex_code_writes_vertex;
 	bool vertex_code_writes_vertex;
 	Flags *flags;
 	Flags *flags;
 
 
@@ -70,6 +71,7 @@ private:
 	StringName vname_time;
 	StringName vname_time;
 	StringName vname_normalmap;
 	StringName vname_normalmap;
 	StringName vname_normal;
 	StringName vname_normal;
+	StringName vname_texpixel_size;
 
 
 	Map<StringName,ShaderLanguage::Uniform> *uniforms;
 	Map<StringName,ShaderLanguage::Uniform> *uniforms;
 
 
@@ -104,6 +106,7 @@ public:
 		bool uses_light;
 		bool uses_light;
 		bool uses_time;
 		bool uses_time;
 		bool uses_normal;
 		bool uses_normal;
+		bool uses_texpixel_size;
 	};
 	};
 
 
 	Error compile(const String& p_code, ShaderLanguage::ShaderType p_type, String& r_code_line, String& r_globals_line, Flags& r_flags, Map<StringName,ShaderLanguage::Uniform> *r_uniforms=NULL);
 	Error compile(const String& p_code, ShaderLanguage::ShaderType p_type, String& r_code_line, String& r_globals_line, Flags& r_flags, Map<StringName,ShaderLanguage::Uniform> *r_uniforms=NULL);

+ 5 - 0
drivers/gles2/shaders/canvas.glsl

@@ -132,6 +132,11 @@ uniform float shadow_attenuation;
 
 
 #endif
 #endif
 
 
+#if defined(USE_TEXPIXEL_SIZE)
+uniform vec2 texpixel_size;
+#endif
+
+
 FRAGMENT_SHADER_GLOBALS
 FRAGMENT_SHADER_GLOBALS
 
 
 
 

+ 1 - 0
scene/gui/grid_container.cpp

@@ -226,5 +226,6 @@ Size2 GridContainer::get_minimum_size() const {
 
 
 GridContainer::GridContainer() {
 GridContainer::GridContainer() {
 
 
+	set_stop_mouse(false);
 	columns=1;
 	columns=1;
 }
 }

+ 2 - 0
servers/visual/rasterizer.h

@@ -210,6 +210,8 @@ public:
 	virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0;
 	virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture)=0;
 	virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0;
 	virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const=0;
 
 
+	virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name)=0;
+
 	/* COMMON MATERIAL API */
 	/* COMMON MATERIAL API */
 
 
 	virtual RID material_create()=0;
 	virtual RID material_create()=0;

+ 5 - 0
servers/visual/rasterizer_dummy.cpp

@@ -231,6 +231,11 @@ RID RasterizerDummy::shader_get_default_texture_param(RID p_shader, const String
 	return RID();
 	return RID();
 }
 }
 
 
+Variant RasterizerDummy::shader_get_default_param(RID p_shader, const StringName& p_name) {
+
+	return Variant();
+}
+
 /* COMMON MATERIAL API */
 /* COMMON MATERIAL API */
 
 
 
 

+ 2 - 0
servers/visual/rasterizer_dummy.h

@@ -433,6 +433,8 @@ public:
 	virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
 	virtual void shader_set_default_texture_param(RID p_shader, const StringName& p_name, RID p_texture);
 	virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
 	virtual RID shader_get_default_texture_param(RID p_shader, const StringName& p_name) const;
 
 
+	virtual Variant shader_get_default_param(RID p_shader, const StringName& p_name);
+
 	/* COMMON MATERIAL API */
 	/* COMMON MATERIAL API */
 
 
 	virtual RID material_create();
 	virtual RID material_create();

+ 2 - 0
servers/visual/shader_language.cpp

@@ -1127,11 +1127,13 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_vertex_builtins_defs[]={
 };
 };
 const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={
 const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={
 
 
+	{ "SRC_COLOR", TYPE_VEC4},
 	{ "POSITION", TYPE_VEC4},
 	{ "POSITION", TYPE_VEC4},
 	{ "NORMAL", TYPE_VEC3},
 	{ "NORMAL", TYPE_VEC3},
 	{ "UV", TYPE_VEC2},
 	{ "UV", TYPE_VEC2},
 	{ "COLOR", TYPE_VEC4},
 	{ "COLOR", TYPE_VEC4},
 	{ "TEXTURE", TYPE_TEXTURE},
 	{ "TEXTURE", TYPE_TEXTURE},
+	{ "TEXTURE_PIXEL_SIZE", TYPE_VEC2},
 	{ "VAR1", TYPE_VEC4},
 	{ "VAR1", TYPE_VEC4},
 	{ "VAR2", TYPE_VEC4},
 	{ "VAR2", TYPE_VEC4},
 	{ "SCREEN_UV", TYPE_VEC2},
 	{ "SCREEN_UV", TYPE_VEC2},

+ 4 - 1
servers/visual/visual_server_raster.cpp

@@ -3730,7 +3730,10 @@ Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, cons
 
 
 	CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
 	CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
 	ERR_FAIL_COND_V(!canvas_item,Variant());
 	ERR_FAIL_COND_V(!canvas_item,Variant());
-	ERR_FAIL_COND_V(!canvas_item->shader_param.has(p_param),Variant());
+	if (!canvas_item->shader_param.has(p_param)) {
+		ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant());
+		return rasterizer->shader_get_default_param(canvas_item->shader,p_param);
+	}
 
 
 	return canvas_item->shader_param[p_param];
 	return canvas_item->shader_param[p_param];
 }
 }