Implemented shader-side recoloring in HSV and added more material tags
parent
7d31b1e55d
commit
a88d9cdd39
|
@ -74,6 +74,8 @@ struct Material
|
|||
CullFace cullFace = CullFace::BACK;
|
||||
// Special tag
|
||||
std::string tag = "";
|
||||
// Recolor reference color
|
||||
Color recolorReference = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Legacy functionality
|
||||
//! Variable detail texture
|
||||
|
@ -95,6 +97,7 @@ struct Material
|
|||
&& alphaThreshold == other.alphaThreshold
|
||||
&& cullFace == other.cullFace
|
||||
&& tag == other.tag
|
||||
&& recolorReference == other.recolorReference
|
||||
&& variableDetail == other.variableDetail
|
||||
&& detailTexture == other.detailTexture;
|
||||
}
|
||||
|
|
|
@ -198,6 +198,9 @@ public:
|
|||
//! Sets alpha scissor
|
||||
virtual void SetAlphaScissor(float alpha) = 0;
|
||||
|
||||
//! Sets recolor parameters
|
||||
virtual void SetRecolor(bool enabled, const glm::vec3& from = {}, const glm::vec3& to = {}, float threshold = {}) = 0;
|
||||
|
||||
//! Sets depth test
|
||||
virtual void SetDepthTest(bool enabled) = 0;
|
||||
//! Sets depth mask
|
||||
|
|
|
@ -2374,11 +2374,6 @@ void CEngine::SetOverColor(const Color& color, TransparencyMode mode)
|
|||
m_overMode = mode;
|
||||
}
|
||||
|
||||
void CEngine::SetTeamColor(int team, const Color& color)
|
||||
{
|
||||
m_teamColors[team] = color;
|
||||
}
|
||||
|
||||
void CEngine::SetParticleDensity(float value)
|
||||
{
|
||||
if (value < 0.0f) value = 0.0f;
|
||||
|
@ -2946,9 +2941,54 @@ void CEngine::Draw3DScene()
|
|||
|
||||
Color color = data.material.albedoColor;
|
||||
|
||||
bool recolor = false;
|
||||
Color recolorFrom = {};
|
||||
Color recolorTo = {};
|
||||
float recolorTreshold = 0.0;
|
||||
|
||||
if (data.material.tag == "team")
|
||||
{
|
||||
color = m_teamColors[m_objects[objRank].team];
|
||||
color = CRobotMain::GetInstance().GetTeamColor(m_objects[objRank].team);
|
||||
}
|
||||
else if (data.material.tag == "vehicle")
|
||||
{
|
||||
color = CRobotMain::GetInstance().GetVehicleColor();
|
||||
}
|
||||
else if (data.material.tag == "plant")
|
||||
{
|
||||
color = CRobotMain::GetInstance().GetGreeneryColor();
|
||||
}
|
||||
else if (data.material.tag == "alien")
|
||||
{
|
||||
color = CRobotMain::GetInstance().GetAlienColor();
|
||||
}
|
||||
else if (data.material.tag == "recolor_team")
|
||||
{
|
||||
recolor = true;
|
||||
recolorFrom = data.material.recolorReference;
|
||||
recolorTo = CRobotMain::GetInstance().GetTeamColor(m_objects[objRank].team);
|
||||
recolorTreshold = 0.1;
|
||||
}
|
||||
else if (data.material.tag == "recolor_vehicle")
|
||||
{
|
||||
recolor = true;
|
||||
recolorFrom = data.material.recolorReference;
|
||||
recolorTo = CRobotMain::GetInstance().GetVehicleColor();
|
||||
recolorTreshold = 0.1;
|
||||
}
|
||||
else if (data.material.tag == "recolor_plant")
|
||||
{
|
||||
recolor = true;
|
||||
recolorFrom = data.material.recolorReference;
|
||||
recolorTo = CRobotMain::GetInstance().GetGreeneryColor();
|
||||
recolorTreshold = 0.1;
|
||||
}
|
||||
else if (data.material.tag == "recolor_alien")
|
||||
{
|
||||
recolor = true;
|
||||
recolorFrom = data.material.recolorReference;
|
||||
recolorTo = CRobotMain::GetInstance().GetAlienColor();
|
||||
recolorTreshold = 0.1;
|
||||
}
|
||||
|
||||
objectRenderer->SetAlbedoColor(color);
|
||||
|
@ -2961,6 +3001,8 @@ void CEngine::Draw3DScene()
|
|||
objectRenderer->SetMaterialParams(data.material.roughness, data.material.metalness, data.material.aoStrength);
|
||||
objectRenderer->SetMaterialTexture(data.materialTexture);
|
||||
|
||||
objectRenderer->SetRecolor(recolor, recolorFrom, recolorTo, recolorTreshold);
|
||||
|
||||
objectRenderer->SetCullFace(data.material.cullFace);
|
||||
objectRenderer->SetUVTransform(data.uvOffset, data.uvScale);
|
||||
objectRenderer->DrawObject(data.buffer);
|
||||
|
|
|
@ -827,8 +827,6 @@ public:
|
|||
void SetOverFront(bool front);
|
||||
//! Sets the foreground overlay color
|
||||
void SetOverColor(const Color& color, TransparencyMode mode);
|
||||
//! Sets color for a team
|
||||
void SetTeamColor(int team, const Color& color);
|
||||
|
||||
//@{
|
||||
//! Management of the particle density
|
||||
|
|
|
@ -209,6 +209,17 @@ void GLTFLoader::ReadMaterials()
|
|||
mat.tag = extras["tag"].get<std::string>();
|
||||
}
|
||||
|
||||
if (extras.contains("recolor_ref"))
|
||||
{
|
||||
const auto& color = extras["recolor_ref"];
|
||||
|
||||
float r = color[0];
|
||||
float g = color[1];
|
||||
float b = color[2];
|
||||
|
||||
mat.recolorReference = Color(r, g, b);
|
||||
}
|
||||
|
||||
if (extras.contains("energy"))
|
||||
{
|
||||
if (extras["energy"].get<int>() != 0)
|
||||
|
|
|
@ -97,6 +97,12 @@ CGL33ObjectRenderer::CGL33ObjectRenderer(CGL33Device* device)
|
|||
m_triplanarMode = glGetUniformLocation(m_program, "uni_TriplanarMode");
|
||||
m_triplanarScale = glGetUniformLocation(m_program, "uni_TriplanarScale");
|
||||
m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor");
|
||||
|
||||
m_recolor = glGetUniformLocation(m_program, "uni_Recolor");
|
||||
m_recolorFrom = glGetUniformLocation(m_program, "uni_RecolorFrom");
|
||||
m_recolorTo = glGetUniformLocation(m_program, "uni_RecolorTo");
|
||||
m_recolorThreshold = glGetUniformLocation(m_program, "uni_RecolorThreshold");
|
||||
|
||||
m_uvOffset = glGetUniformLocation(m_program, "uni_UVOffset");
|
||||
m_uvScale = glGetUniformLocation(m_program, "uni_UVScale");
|
||||
|
||||
|
@ -211,6 +217,7 @@ void CGL33ObjectRenderer::CGL33ObjectRenderer::Begin()
|
|||
SetEmissiveColor({ 0, 0, 0, 0 });
|
||||
SetAlbedoColor({ 1, 1, 1, 1 });
|
||||
SetMaterialParams(1.0, 0.0, 0.0);
|
||||
SetRecolor(false);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::CGL33ObjectRenderer::End()
|
||||
|
@ -427,6 +434,21 @@ void CGL33ObjectRenderer::SetAlphaScissor(float alpha)
|
|||
glUniform1f(m_alphaScissor, alpha);
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetRecolor(bool enabled, const glm::vec3& from, const glm::vec3& to, float threshold)
|
||||
{
|
||||
glUniform1i(m_recolor, enabled ? 1 : 0);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
auto fromHSV = RGB2HSV(Color(from.r, from.g, from.b, 1.0));
|
||||
auto toHSV = RGB2HSV(Color(to.r, to.g, to.b, 1.0));
|
||||
|
||||
glUniform3f(m_recolorFrom, fromHSV.h, fromHSV.s, fromHSV.v);
|
||||
glUniform3f(m_recolorTo, toHSV.h, toHSV.s, toHSV.v);
|
||||
glUniform1f(m_recolorThreshold, threshold);
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::DrawObject(const CVertexBuffer* buffer)
|
||||
{
|
||||
auto b = dynamic_cast<const CGL33VertexBuffer*>(buffer);
|
||||
|
|
|
@ -86,6 +86,9 @@ public:
|
|||
//! Sets alpha scissor
|
||||
virtual void SetAlphaScissor(float alpha) override;
|
||||
|
||||
//! Sets recolor parameters
|
||||
virtual void SetRecolor(bool enabled, const glm::vec3& from = {}, const glm::vec3& to = {}, float threshold = {}) override;
|
||||
|
||||
virtual void SetDepthTest(bool enabled) override;
|
||||
virtual void SetDepthMask(bool enabled) override;
|
||||
|
||||
|
@ -141,6 +144,11 @@ private:
|
|||
GLint m_triplanarScale = -1;
|
||||
GLint m_alphaScissor = -1;
|
||||
|
||||
GLint m_recolor = -1;
|
||||
GLint m_recolorFrom = -1;
|
||||
GLint m_recolorTo = -1;
|
||||
GLint m_recolorThreshold = -1;
|
||||
|
||||
GLint m_uvOffset = -1;
|
||||
GLint m_uvScale = -1;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// FRAGMENT SHADER - TERRAIN RENDERER
|
||||
// FRAGMENT SHADER - OBJECT RENDERER
|
||||
|
||||
uniform vec2 uni_FogRange;
|
||||
uniform vec3 uni_FogColor;
|
||||
|
@ -39,6 +39,11 @@ uniform float uni_TriplanarScale;
|
|||
|
||||
uniform float uni_AlphaScissor;
|
||||
|
||||
uniform bool uni_Recolor;
|
||||
uniform vec3 uni_RecolorFrom;
|
||||
uniform vec3 uni_RecolorTo;
|
||||
uniform float uni_RecolorThreshold;
|
||||
|
||||
in VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
|
@ -64,11 +69,48 @@ vec3 Triplanar(vec3 position, vec3 normal)
|
|||
return sum;
|
||||
}
|
||||
|
||||
// All components are in the range [0...1], including hue.
|
||||
vec3 rgb2hsv(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));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
// All components are in the range [0...1], including hue.
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 albedo = data.Color * uni_AlbedoColor;
|
||||
|
||||
albedo *= texture(uni_AlbedoTexture, data.TexCoord0);
|
||||
vec4 texColor = texture(uni_AlbedoTexture, data.TexCoord0);
|
||||
|
||||
if (uni_Recolor)
|
||||
{
|
||||
vec3 hsv = rgb2hsv(texColor.rgb);
|
||||
|
||||
if (abs(hsv.x - uni_RecolorFrom.x) < uni_RecolorThreshold)
|
||||
{
|
||||
hsv += (uni_RecolorTo - uni_RecolorFrom);
|
||||
|
||||
if (hsv.x < 0.0) hsv.x += 1.0;
|
||||
if (hsv.x > 1.0) hsv.x -= 1.0;
|
||||
}
|
||||
|
||||
texColor.rgb = hsv2rgb(hsv);
|
||||
}
|
||||
|
||||
albedo *= texColor;
|
||||
|
||||
vec3 dirty = vec3(0.0);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// VERTEX SHADER - TERRAIN RENDERER
|
||||
// VERTEX SHADER - OBJECT RENDERER
|
||||
|
||||
uniform mat4 uni_ProjectionMatrix;
|
||||
uniform mat4 uni_ViewMatrix;
|
||||
|
|
|
@ -4036,10 +4036,6 @@ void CRobotMain::ChangeColor()
|
|||
{
|
||||
int team = it.first;
|
||||
Gfx::Color newColor = it.second;
|
||||
std::string teamStr = StrUtils::ToString<int>(team);
|
||||
if(team == 0) teamStr = "";
|
||||
|
||||
m_engine->SetTeamColor(team, newColor);
|
||||
|
||||
//m_engine->ChangeTextureColor("textures/objects/base1.png"+teamStr, "textures/objects/base1.png", COLOR_REF_BOT, newColor, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, nullptr, 0, true);
|
||||
//m_engine->ChangeTextureColor("textures/objects/convert.png"+teamStr, "textures/objects/convert.png", COLOR_REF_BOT, newColor, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, nullptr, 0, true);
|
||||
|
@ -6000,6 +5996,34 @@ void CRobotMain::MarkResearchDone(ResearchType type, int team)
|
|||
}
|
||||
}
|
||||
|
||||
const Gfx::Color& CRobotMain::GetTeamColor(int team)
|
||||
{
|
||||
if (m_colorNewBot.count(team) > 0)
|
||||
return m_colorNewBot.at(team);
|
||||
else
|
||||
return m_colorNewBot.at(0);
|
||||
}
|
||||
|
||||
const Gfx::Color& CRobotMain::GetVehicleColor()
|
||||
{
|
||||
return m_colorNewBot.at(0);
|
||||
}
|
||||
|
||||
const Gfx::Color& CRobotMain::GetAlienColor()
|
||||
{
|
||||
return m_colorNewAlien;
|
||||
}
|
||||
|
||||
const Gfx::Color& CRobotMain::GetGreeneryColor()
|
||||
{
|
||||
return m_colorNewGreen;
|
||||
}
|
||||
|
||||
const Gfx::Color& CRobotMain::GetWaterColor()
|
||||
{
|
||||
return m_colorNewWater;
|
||||
}
|
||||
|
||||
Error CRobotMain::CanBuildError(ObjectType type, int team)
|
||||
{
|
||||
if(!IsBuildingEnabled(type)) return ERR_BUILD_DISABLED;
|
||||
|
|
|
@ -440,6 +440,17 @@ public:
|
|||
//! \brief Mark given research as done
|
||||
void MarkResearchDone(ResearchType type, int team);
|
||||
|
||||
//! \brief Returns a color associated with a team or vehicle color if none defined
|
||||
const Gfx::Color& GetTeamColor(int team);
|
||||
//! \brief Returns vehicle color
|
||||
const Gfx::Color& GetVehicleColor();
|
||||
//! \brief Returns alien color
|
||||
const Gfx::Color& GetAlienColor();
|
||||
//! \brief Returns plant color
|
||||
const Gfx::Color& GetGreeneryColor();
|
||||
//! \brief Returns water color
|
||||
const Gfx::Color& GetWaterColor();
|
||||
|
||||
/**
|
||||
* \brief Check if all requirements to build this object are met (EnableBuild + DoneResearch)
|
||||
* \return true if the building can be built, false otherwise
|
||||
|
|
Loading…
Reference in New Issue