diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 74 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 15 | ||||
-rw-r--r-- | drivers/gles2/shader_compiler_gles2.h | 3 | ||||
-rw-r--r-- | drivers/gles2/shaders/canvas.glsl | 17 |
4 files changed, 77 insertions, 32 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 9375532f07..5903be9d81 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4588,6 +4588,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { enablers.push_back("#define USE_TEXPIXEL_SIZE\n"); } + if (vertex_flags.uses_worldvec) { + enablers.push_back("#define USE_WORLD_VEC\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); //postprocess_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names); @@ -4954,12 +4957,26 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ Material::UniformData ud; bool keep=true; //keep material value - bool has_old = old_mparams.has(E->key()); + + Map<StringName,Material::UniformData>::Element *OLD=old_mparams.find(E->key()); + bool has_old = OLD; bool old_inuse=has_old && old_mparams[E->key()].inuse; - if (!has_old || !old_inuse) + ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP); + + if (!has_old || !old_inuse) { keep=false; - else if (old_mparams[E->key()].value.get_type()!=E->value().default_value.get_type()) { + } + else if (OLD->get().value.get_type()!=E->value().default_value.get_type()) { + + if (OLD->get().value.get_type()==Variant::INT && E->get().type==ShaderLanguage::TYPE_FLOAT) { + //handle common mistake using shaders (feeding ints instead of float) + OLD->get().value=float(OLD->get().value); + keep=true; + } else if (!ud.istexture && E->value().default_value.get_type()!=Variant::NIL) { + + keep=false; + } //type changed between old and new /* if (old_mparams[E->key()].value.get_type()==Variant::OBJECT) { if (E->value().default_value.get_type()!=Variant::_RID) //hackfor textures @@ -4968,11 +4985,9 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_ keep=false;*/ //value is invalid because type differs and default is not null - if (E->value().default_value.get_type()!=Variant::NIL) - keep=false; + ; } - ud.istexture=(E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP); if (keep) { ud.value=old_mparams[E->key()].value; @@ -5096,8 +5111,10 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material int texcoord=0; for (Map<StringName,Material::UniformData>::Element *E=p_material->shader_params.front();E;E=E->next()) { + if (E->get().index<0) continue; +// print_line(String(E->key())+": "+E->get().value); if (E->get().istexture) { //clearly a texture.. RID rid = E->get().value; @@ -8362,24 +8379,39 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { int idx=0; for(Map<StringName,ShaderLanguage::Uniform>::Element *E=shader->uniforms.front();E;E=E->next()) { - Map<StringName,Variant>::Element *F=shader_owner->shader_param.find(E->key()); - Variant &v=F?F->get():E->get().default_value; - if (v.get_type()==Variant::_RID || v.get_type()==Variant::OBJECT) { - int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic.. - - glActiveTexture(GL_TEXTURE0+tex_id); - RID tex = v; - Texture *t=texture_owner.get(tex); - if (!t) - glBindTexture(GL_TEXTURE_2D,white_tex); - else - glBindTexture(t->target,t->tex_id); - glUniform1i(loc,tex_id); - tex_id++; + if ((E->get().type==ShaderLanguage::TYPE_TEXTURE || E->get().type==ShaderLanguage::TYPE_CUBEMAP)) { + + RID rid; + if (F) { + rid=F->get(); + } + + if (!rid.is_valid()) { + + Map<StringName,RID>::Element *DT=shader->default_textures.find(E->key()); + if (DT) { + rid=DT->get(); + } + } + + if (rid.is_valid()) { + int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic.. + + glActiveTexture(GL_TEXTURE0+tex_id); + Texture *t=texture_owner.get(rid); + if (!t) + glBindTexture(GL_TEXTURE_2D,white_tex); + else + glBindTexture(t->target,t->tex_id); + + glUniform1i(loc,tex_id); + tex_id++; + } } else { + Variant &v=F?F->get():E->get().default_value; canvas_shader.set_custom_uniform(idx,v); } @@ -8403,7 +8435,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) { #endif glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); if (current_clip) { - print_line(" a clip "); + // print_line(" a clip "); } canvas_texscreen_used=true; diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index f1ddcf8009..d8841d407e 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -226,6 +226,9 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a if (vnode->name==vname_var2_interp) { flags->use_var2_interp=true; } + if (vnode->name==vname_world_vec) { + uses_worldvec=true; + } } @@ -307,13 +310,13 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a String mul_l=dump_node_code(onode->arguments[0],p_level,true); String mul_r=dump_node_code(onode->arguments[1],p_level); - code=mul_l+"=(vec4("+mul_l+",1.0,1.0)*("+mul_r+")).xy"; + code=mul_l+"=(vec4("+mul_l+",0.0,1.0)*("+mul_r+")).xy"; break; } else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT4 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC2) { String mul_l=dump_node_code(onode->arguments[0],p_level,true); String mul_r=dump_node_code(onode->arguments[1],p_level); - code=mul_l+"=(("+mul_l+")*vec4("+mul_r+",1.0,1.0)).xy"; + code=mul_l+"=(("+mul_l+")*vec4("+mul_r+",0.0,1.0)).xy"; break; } else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC2 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT3) { String mul_l=dump_node_code(onode->arguments[0],p_level,true); @@ -343,11 +346,11 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a break; } else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT4 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC2) { - code="("+dump_node_code(onode->arguments[0],p_level)+"*vec4("+dump_node_code(onode->arguments[1],p_level)+",1.0,1.0)).xyz"; + code="("+dump_node_code(onode->arguments[0],p_level)+"*vec4("+dump_node_code(onode->arguments[1],p_level)+",0.0,1.0)).xy"; break; } else if (onode->arguments[0]->get_datatype()==SL::TYPE_VEC2 && onode->arguments[1]->get_datatype()==SL::TYPE_MAT4) { - code="(vec4("+dump_node_code(onode->arguments[0],p_level)+",1.0,1.0)*"+dump_node_code(onode->arguments[1],p_level)+").xyz"; + code="(vec4("+dump_node_code(onode->arguments[0],p_level)+",0.0,1.0)*"+dump_node_code(onode->arguments[1],p_level)+").xy"; break; } else if (onode->arguments[0]->get_datatype()==SL::TYPE_MAT3 && onode->arguments[1]->get_datatype()==SL::TYPE_VEC2) { @@ -599,6 +602,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT uses_normalmap=false; uses_normal=false; uses_texpixel_size=false; + uses_worldvec=false; vertex_code_writes_vertex=false; uniforms=r_uniforms; flags=&r_flags; @@ -634,6 +638,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.uses_normalmap=uses_normalmap; r_flags.uses_normal=uses_normalmap; r_flags.uses_texpixel_size=uses_texpixel_size; + r_flags.uses_worldvec=uses_worldvec; r_code_line=code; r_globals_line=global_code; @@ -774,6 +779,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { mode_replace_table[3]["SRC_VERTEX"]="src_vtx"; mode_replace_table[3]["VERTEX"]="outvec.xy"; + mode_replace_table[3]["WORLD_VERTEX"]="outvec.xy"; mode_replace_table[3]["UV"]="uv_interp"; mode_replace_table[3]["COLOR"]="color_interp"; mode_replace_table[3]["VAR1"]="var1_interp"; @@ -830,5 +836,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { vname_normalmap="NORMALMAP"; vname_normal="NORMAL"; vname_texpixel_size="TEXTURE_PIXEL_SIZE"; + vname_world_vec="WORLD_VERTEX"; } diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index a10fa6dfe0..87722602fd 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -53,6 +53,7 @@ private: bool uses_normalmap; bool uses_normal; bool uses_texpixel_size; + bool uses_worldvec; bool vertex_code_writes_vertex; Flags *flags; @@ -72,6 +73,7 @@ private: StringName vname_normalmap; StringName vname_normal; StringName vname_texpixel_size; + StringName vname_world_vec; Map<StringName,ShaderLanguage::Uniform> *uniforms; @@ -107,6 +109,7 @@ public: bool uses_time; bool uses_normal; bool uses_texpixel_size; + bool uses_worldvec; }; 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); diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 464cb9e188..dc0af017d0 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -46,29 +46,32 @@ void main() { color_interp = color_attrib; uv_interp = uv_attrib; - highp vec4 outvec = vec4(vertex, 1.0); + highp vec4 outvec = vec4(vertex, 1.0); { - vec2 src_vtx=outvec.xy; + vec2 src_vtx=outvec.xy; VERTEX_SHADER_CODE } - outvec = extra_matrix * outvec; - outvec = modelview_matrix * outvec; +#if !defined(USE_WORLD_VEC) + outvec = extra_matrix * outvec; + outvec = modelview_matrix * outvec; +#endif + #ifdef USE_PIXEL_SNAP outvec.xy=floor(outvec.xy+0.5); #endif + gl_Position = projection_matrix * outvec; + #ifdef USE_LIGHTING - light_tex_pos.xy = light_matrix * outvec; + light_tex_pos.xy = light_matrix * gl_Position; light_tex_pos.zw=outvec.xy - light_matrix[4].xy; //likely wrong #endif - - gl_Position = projection_matrix * outvec; } [fragment] |