From 544ce2a1dbaa5548490c975c2f6f6ed7c21377b9 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 12 Jan 2015 10:19:09 -0300 Subject: [PATCH] -Initial working(?) implementation of shaders for 2D. Lighting still not there though. Check for reference: https://github.com/okamstudio/godot/wiki/shader --- drivers/gles2/rasterizer_gles2.cpp | 38 +++++++++++++++-- drivers/gles2/rasterizer_gles2.h | 5 +++ drivers/gles2/shader_compiler_gles2.cpp | 54 +++++++++++++++++++++++-- drivers/gles2/shader_compiler_gles2.h | 3 ++ drivers/gles2/shaders/canvas.glsl | 5 +++ scene/gui/grid_container.cpp | 1 + servers/visual/rasterizer.h | 2 + servers/visual/rasterizer_dummy.cpp | 5 +++ servers/visual/rasterizer_dummy.h | 2 + servers/visual/shader_language.cpp | 2 + servers/visual/visual_server_raster.cpp | 5 ++- 11 files changed, 115 insertions(+), 7 deletions(-) diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 2d60f0e9281..80dd1a78982 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/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{ const Shader *shader=shader_owner.get(p_shader); + ERR_FAIL_COND_V(!shader,RID()); const Map::Element *E=shader->default_textures.find(p_name); if (!E) @@ -1571,6 +1572,22 @@ RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const String 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 */ @@ -4567,6 +4584,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { if (fragment_flags.uses_screen_uv) { 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); @@ -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->uses_normal=fragment_flags.uses_normal || light_flags.uses_normal; p_shader->uses_time=uses_time; + p_shader->uses_texpixel_size=fragment_flags.uses_texpixel_size; p_shader->version++; } @@ -7874,7 +7895,7 @@ void RasterizerGLES2::canvas_end_rect() { 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()) { Texture*texture=texture_owner.get(p_texture); return texture; @@ -7882,14 +7903,16 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex return NULL; } - + rebind_texpixel_size=false; if (p_texture.is_valid()) { + Texture*texture=texture_owner.get(p_texture); if (!texture) { canvas_tex=RID(); glBindTexture(GL_TEXTURE_2D,white_tex); + return NULL; } @@ -7898,6 +7921,9 @@ RasterizerGLES2::Texture* RasterizerGLES2::_bind_canvas_texture(const RID& p_tex glBindTexture(GL_TEXTURE_2D,texture->tex_id); 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; @@ -8281,6 +8307,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { csy = -1.0; 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); @@ -8330,7 +8358,8 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { if (shader) { 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) { //todo optimize uniforms @@ -8383,9 +8412,12 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { } //if uses TIME - draw_next_frame=true + uses_texpixel_size=shader->uses_texpixel_size; + } else { canvas_shader.set_custom_shader(0); canvas_shader.bind(); + uses_texpixel_size=false; } diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index f0dae00b53b..65947fb0349 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -192,6 +192,7 @@ class RasterizerGLES2 : public Rasterizer { bool uses_discard; bool uses_time; bool uses_normal; + bool uses_texpixel_size; Map uniforms; StringName first_texture; @@ -1171,6 +1172,8 @@ class RasterizerGLES2 : public Rasterizer { GLuint white_tex; RID canvas_tex; float canvas_opacity; + bool uses_texpixel_size; + bool rebind_texpixel_size; _FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture); 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 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 */ virtual RID material_create(); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 163d1460090..93b0ecc61f4 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/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; case SL::Node::TYPE_VARIABLE: { SL::VariableNode *vnode=(SL::VariableNode*)p_node; + if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) { 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 (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) { uses_normalmap=true; } - if (vnode->name==vname_normal) { - uses_normal=true; - } if (vnode->name==vname_screen_uv) { 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; } + } + 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) { @@ -556,6 +598,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT uses_time=false; uses_normalmap=false; uses_normal=false; + uses_texpixel_size=false; vertex_code_writes_vertex=false; uniforms=r_uniforms; 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_normalmap=uses_normalmap; r_flags.uses_normal=uses_normalmap; + r_flags.uses_texpixel_size=uses_texpixel_size; r_code_line=code; r_globals_line=global_code; @@ -742,14 +786,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { mode_replace_table[4]["POSITION"]="gl_Position"; mode_replace_table[4]["NORMAL"]="normal"; 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]["TEXTURE"]="texture"; + mode_replace_table[4]["TEXTURE_PIXEL_SIZE"]="texpixel_size"; mode_replace_table[4]["VAR1"]="var1_interp"; mode_replace_table[4]["VAR2"]="var2_interp"; mode_replace_table[4]["SCREEN_UV"]="screen_uv"; mode_replace_table[4]["POINT_COORD"]="gl_PointCoord"; mode_replace_table[4]["TIME"]="time"; + mode_replace_table[5]["SRC_COLOR"]="color"; mode_replace_table[5]["COLOR"]="color"; mode_replace_table[5]["NORMAL"]="normal"; mode_replace_table[5]["LIGHT_DIR"]="light_dir"; @@ -781,5 +828,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { vname_time="TIME"; vname_normalmap="NORMALMAP"; vname_normal="NORMAL"; + vname_texpixel_size="TEXTURE_PIXEL_SIZE"; } diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index 47ba4aa474f..a10fa6dfe08 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -52,6 +52,7 @@ private: bool uses_screen_uv; bool uses_normalmap; bool uses_normal; + bool uses_texpixel_size; bool vertex_code_writes_vertex; Flags *flags; @@ -70,6 +71,7 @@ private: StringName vname_time; StringName vname_normalmap; StringName vname_normal; + StringName vname_texpixel_size; Map *uniforms; @@ -104,6 +106,7 @@ public: bool uses_light; bool uses_time; 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 *r_uniforms=NULL); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 3e7e54e0fed..4ec601f0fcb 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -132,6 +132,11 @@ uniform float shadow_attenuation; #endif +#if defined(USE_TEXPIXEL_SIZE) +uniform vec2 texpixel_size; +#endif + + FRAGMENT_SHADER_GLOBALS diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index f54345cdb8d..582693eb3af 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -226,5 +226,6 @@ Size2 GridContainer::get_minimum_size() const { GridContainer::GridContainer() { + set_stop_mouse(false); columns=1; } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index ecd44fddfd0..346d535ae84 100644 --- a/servers/visual/rasterizer.h +++ b/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 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 */ virtual RID material_create()=0; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 1275b2308cd..6c1b6697c15 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -231,6 +231,11 @@ RID RasterizerDummy::shader_get_default_texture_param(RID p_shader, const String return RID(); } +Variant RasterizerDummy::shader_get_default_param(RID p_shader, const StringName& p_name) { + + return Variant(); +} + /* COMMON MATERIAL API */ diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 2944bbbaf12..fa7f1976921 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/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 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 */ virtual RID material_create(); diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 1b076176f49..80f82fdc42c 100644 --- a/servers/visual/shader_language.cpp +++ b/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[]={ + { "SRC_COLOR", TYPE_VEC4}, { "POSITION", TYPE_VEC4}, { "NORMAL", TYPE_VEC3}, { "UV", TYPE_VEC2}, { "COLOR", TYPE_VEC4}, { "TEXTURE", TYPE_TEXTURE}, + { "TEXTURE_PIXEL_SIZE", TYPE_VEC2}, { "VAR1", TYPE_VEC4}, { "VAR2", TYPE_VEC4}, { "SCREEN_UV", TYPE_VEC2}, diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 7e915be3d52..96aa8732660 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/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 ); 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]; }