diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index 5b85ce4f2..9cb4772c4 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -8,14 +8,14 @@ flat in sampler2D handle; flat in sampler2D secondhandle; #endif -uniform vec2 color_change; +uniform float color_change; in vec2 uv; in vec4 color; out vec4 FragColor; vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue, float emitMapValue); -float rgbToValue(vec3 c); +vec3 rgbToHsv(vec3 c); vec3 hsvToRgb(vec3 c); void main(void) @@ -33,10 +33,12 @@ void main(void) float emitmap = texture(SpecMap, uv).b; #endif - if (color_change.x > 0.0) + if (color_change > 0.0) { - vec3 new_color = hsvToRgb(vec3(color_change.x, color_change.y, rgbToValue(col.rgb))); - col = vec4(new_color.b, new_color.g, new_color.r, col.a); + vec3 old_hsv = rgbToHsv(col.rgb); + old_hsv.y = max(old_hsv.y, 0.93); + vec3 new_color = hsvToRgb(vec3(color_change, old_hsv.y, old_hsv.z)); + col = vec4(new_color.r, new_color.g, new_color.b, col.a); } col.xyz *= pow(color.xyz, vec3(2.2)); diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index ec66df653..818004d0d 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -6,14 +6,14 @@ uniform sampler2D Albedo; uniform sampler2D SpecMap; #endif -uniform vec2 color_change; +uniform float color_change; in vec2 uv; in vec4 color; out vec4 FragColor; vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapValue, float emitMapValue); -float rgbToValue(vec3 c); +vec3 rgbToHsv(vec3 c); vec3 hsvToRgb(vec3 c); void main(void) @@ -27,10 +27,12 @@ void main(void) vec4 col = texture(Albedo, uv); #endif - if (color_change.x > 0.0) + if (color_change > 0.0) { - vec3 new_color = hsvToRgb(vec3(color_change.x, color_change.y, rgbToValue(col.rgb))); - col = vec4(new_color.b, new_color.g, new_color.r, col.a); + vec3 old_hsv = rgbToHsv(col.rgb); + old_hsv.y = max(old_hsv.y, 0.93); + vec3 new_color = hsvToRgb(vec3(color_change, old_hsv.y, old_hsv.z)); + col = vec4(new_color.r, new_color.g, new_color.b, col.a); } col.xyz *= pow(color.xyz, vec3(2.2)); diff --git a/data/shaders/utils/rgb_conversion.frag b/data/shaders/utils/rgb_conversion.frag index ad1838013..6e944a611 100644 --- a/data/shaders/utils/rgb_conversion.frag +++ b/data/shaders/utils/rgb_conversion.frag @@ -9,15 +9,6 @@ vec3 rgbToHsv(vec3 c) return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } -float rgbToValue(vec3 c) -{ - vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); - vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); - - return q.x; -} - vec3 hsvToRgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index b64f1a0e6..bc05dfd72 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -153,10 +153,11 @@ public: 4, "SpecMap", ST_TRILINEAR_ANISOTROPIC_FILTERED); } // InstancedObjectPass2Shader - void setHueSaturation(float hue, float saturation) const + virtual bool changeHue(float hue = 0.0f) const OVERRIDE { - glUniform2f(m_color_change_location, hue, saturation); - } // setHueSaturation + glUniform1f(m_color_change_location, hue); + return true; + } // changeHue }; // InstancedObjectPass2Shader // ============================================================================ @@ -997,23 +998,17 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args) GLenum itype = mesh->IndexType; size_t count = mesh->IndexCount; - const Shaders::ObjectPass2Shader* op2s = dynamic_cast - (Shader); - if (op2s) + const video::E_RENDER_TYPE rt = mesh->mb->getRenderType(); + const bool need_change_hue = (rt != video::ERT_DEFAULT); + if (need_change_hue) { - const video::E_RENDER_TYPE rt = mesh->mb->getRenderType(); if (rt == video::ERT_RED) { - op2s->setHueSaturation(0.69f, 0.97f); + Shader->changeHue(1.0f); } else if (rt == video::ERT_BLUE) { - op2s->setHueSaturation(0.01f, 0.97f); - } - else - { - // Reset if not using custom render type - op2s->setHueSaturation(0.0f, 0.0f); + Shader->changeHue(0.66f); } } @@ -1021,6 +1016,13 @@ void draw(const T *Shader, const GLMesh *mesh, uniforms... Args) glDrawElementsBaseVertex(ptype, (int)count, itype, (GLvoid *)mesh->vaoOffset, (int)mesh->vaoBaseVertex); + + if (need_change_hue) + { + // Reset after changing + Shader->changeHue(); + } + } // draw // ---------------------------------------------------------------------------- @@ -1302,47 +1304,31 @@ void renderInstancedMeshes2ndPass(const std::vector &Prefilled_tex, Args TexExpander::template ExpandTex(*mesh, T::SecondPassTextures, Prefilled_tex[0], Prefilled_tex[1], Prefilled_tex[2]); - T::InstancedSecondPassShader::getInstance()->setUniforms(args...); - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) - * sizeof(DrawElementsIndirectCommand))); - } -} // renderInstancedMeshes2ndPass - -// ---------------------------------------------------------------------------- -template<> -void renderInstancedMeshes2ndPass(const std::vector &Prefilled_tex) -{ - std::vector &meshes = DefaultMaterial::InstancedList::getInstance()->SolidPass; - DefaultMaterial::InstancedSecondPassShader::getInstance()->use(); - glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(DefaultMaterial::VertexType, - DefaultMaterial::Instance)); - for (unsigned i = 0; i < meshes.size(); i++) - { - GLMesh *mesh = meshes[i]; - TexExpander::template - ExpandTex(*mesh, DefaultMaterial::SecondPassTextures, Prefilled_tex[0], - Prefilled_tex[1], Prefilled_tex[2]); const video::E_RENDER_TYPE rt = mesh->mb->getRenderType(); - if (rt == video::ERT_RED) + const bool need_change_hue = (rt != video::ERT_DEFAULT); + if (need_change_hue) { - DefaultMaterial::InstancedSecondPassShader::getInstance()->setHueSaturation(0.69f, 0.97f); - } - else if (rt == video::ERT_BLUE) - { - DefaultMaterial::InstancedSecondPassShader::getInstance()->setHueSaturation(0.01f, 0.97f); - } - else - { - // Reset if not using custom render type - DefaultMaterial::InstancedSecondPassShader::getInstance()->setHueSaturation(0.0f, 0.0f); + if (rt == video::ERT_RED) + { + T::InstancedSecondPassShader::getInstance()->changeHue(1.0f); + } + else if (rt == video::ERT_BLUE) + { + T::InstancedSecondPassShader::getInstance()->changeHue(0.66f); + } } - DefaultMaterial::InstancedSecondPassShader::getInstance()->setUniforms(); + T::InstancedSecondPassShader::getInstance()->setUniforms(args...); glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, - (const void*)((SolidPassCmd::getInstance()->Offset[DefaultMaterial::MaterialType] + i) + (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand))); + + if (need_change_hue) + { + // Reset after changing + T::InstancedSecondPassShader::getInstance()->changeHue(); + } } } // renderInstancedMeshes2ndPass diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index ea4cada42..7ab447d27 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -150,10 +150,11 @@ public: GLint m_color_change_location; public: ObjectPass2Shader(); - void setHueSaturation(float hue, float saturation) const + virtual bool changeHue(float hue = 0.0f) const OVERRIDE { - glUniform2f(m_color_change_location, hue, saturation); - } // setHueSaturation + glUniform1f(m_color_change_location, hue); + return true; + } // changeHue }; // ObjectPass2Shader // ======================================================================== diff --git a/src/graphics/texture_shader.hpp b/src/graphics/texture_shader.hpp index 16222fa7c..61f2f8007 100644 --- a/src/graphics/texture_shader.hpp +++ b/src/graphics/texture_shader.hpp @@ -21,6 +21,7 @@ #include "graphics/central_settings.hpp" #include "graphics/gl_headers.hpp" #include "graphics/shader.hpp" +#include "utils/cpp2011.hpp" #include #include @@ -241,6 +242,12 @@ public: glDeleteSamplers(1, &m_sampler_ids[i]); } // ~TextureShader + /** Override this class and return true if a shader can set different hue. + */ + virtual bool changeHue(float hue = 0.0f) const + { + return false; + } // changeHue }; // class TextureShader