Texture coloring

dev-ui
Piotr Dziwinski 2012-09-29 23:37:38 +02:00
parent 4f097c10b3
commit a8554cfae3
3 changed files with 169 additions and 23 deletions

View File

@ -2082,8 +2082,6 @@ Texture CEngine::CreateTexture(const std::string& texName, const TextureCreatePa
if (m_texBlacklist.find(texName) != m_texBlacklist.end())
return Texture(); // invalid texture
// TODO: detect alpha channel?
CImage img;
if (! img.Load(m_app->GetDataFilePath(DIR_TEXTURE, texName)))
{
@ -2194,6 +2192,146 @@ bool CEngine::LoadAllTextures()
return ok;
}
bool IsExcludeColor(Math::Point *exclude, int x, int y)
{
int i = 0;
while ( exclude[i+0].x != 0.0f || exclude[i+0].y != 0.0f ||
exclude[i+1].y != 0.0f || exclude[i+1].y != 0.0f )
{
if ( x >= static_cast<int>(exclude[i+0].x*256.0f) &&
x < static_cast<int>(exclude[i+1].x*256.0f) &&
y >= static_cast<int>(exclude[i+0].y*256.0f) &&
y < static_cast<int>(exclude[i+1].y*256.0f) ) return true; // exclude
i += 2;
}
return false; // point to include
}
bool CEngine::ChangeTextureColor(const std::string& texName,
Color colorRef1, Color colorNew1,
Color colorRef2, Color colorNew2,
float tolerance1, float tolerance2,
Math::Point ts, Math::Point ti,
Math::Point *exclude, float shift, bool hsv)
{
if ( colorRef1.r == colorNew1.r &&
colorRef1.g == colorNew1.g &&
colorRef1.b == colorNew1.b &&
colorRef2.r == colorNew2.r &&
colorRef2.g == colorNew2.g &&
colorRef2.b == colorNew2.b ) return true;
DeleteTexture(texName);
CImage img;
if (! img.Load(m_app->GetDataFilePath(DIR_TEXTURE, texName)))
{
std::string error = img.GetError();
GetLogger()->Error("Couldn't load texture '%s': %s, blacklisting\n", texName.c_str(), error.c_str());
m_texBlacklist.insert(texName);
return false;
}
int dx = img.GetSize().x;
int dy = img.GetSize().x;
int sx = static_cast<int>(ts.x*dx);
int sy = static_cast<int>(ts.y*dy);
int ex = static_cast<int>(ti.x*dx);
int ey = static_cast<int>(ti.y*dy);
ColorHSV cr1 = RGB2HSV(colorRef1);
ColorHSV cn1 = RGB2HSV(colorNew1);
ColorHSV cr2 = RGB2HSV(colorRef2);
ColorHSV cn2 = RGB2HSV(colorNew2);
for (int y = sy; y < ey; y++)
{
for (int x = sx; x < ex; x++)
{
if (exclude != nullptr && IsExcludeColor(exclude, x,y) ) continue;
Color color = img.GetPixel(Math::IntPoint(x, y));
if (hsv)
{
ColorHSV c = RGB2HSV(color);
if (c.s > 0.01f && fabs(c.h - cr1.h) < tolerance1)
{
c.h += cn1.h - cr1.h;
c.s += cn1.s - cr1.s;
c.v += cn1.v - cr1.v;
if (c.h < 0.0f) c.h -= 1.0f;
if (c.h > 1.0f) c.h += 1.0f;
color = HSV2RGB(c);
color.r += shift;
color.g += shift;
color.b += shift;
img.SetPixel(Math::IntPoint(x, y), color);
}
else if (tolerance2 != -1.0f &&
c.s > 0.01f && fabs(c.h - cr2.h) < tolerance2)
{
c.h += cn2.h - cr2.h;
c.s += cn2.s - cr2.s;
c.v += cn2.v - cr2.v;
if (c.h < 0.0f) c.h -= 1.0f;
if (c.h > 1.0f) c.h += 1.0f;
color = HSV2RGB(c);
color.r += shift;
color.g += shift;
color.b += shift;
img.SetPixel(Math::IntPoint(x, y), color);
}
}
else
{
if ( fabs(color.r - colorRef1.r) +
fabs(color.g - colorRef1.g) +
fabs(color.b - colorRef1.b) < tolerance1 * 3.0f)
{
color.r = colorNew1.r + color.r - colorRef1.r + shift;
color.g = colorNew1.g + color.g - colorRef1.g + shift;
color.b = colorNew1.b + color.b - colorRef1.b + shift;
img.SetPixel(Math::IntPoint(x, y), color);
}
else if (tolerance2 != -1 &&
fabs(color.r - colorRef2.r) +
fabs(color.g - colorRef2.g) +
fabs(color.b - colorRef2.b) < tolerance2 * 3.0f)
{
color.r = colorNew2.r + color.r - colorRef2.r + shift;
color.g = colorNew2.g + color.g - colorRef2.g + shift;
color.b = colorNew2.b + color.b - colorRef2.b + shift;
img.SetPixel(Math::IntPoint(x, y), color);
}
}
}
}
Texture tex = m_device->CreateTexture(&img, m_defaultTexParams);
if (! tex.Valid())
{
GetLogger()->Error("Couldn't load texture '%s', blacklisting\n", texName.c_str());
m_texBlacklist.insert(texName);
return false;
}
m_texNameMap[texName] = tex;
m_revTexNameMap[tex] = texName;
return true;
}
void CEngine::DeleteTexture(const std::string& texName)
{
auto it = m_texNameMap.find(texName);

View File

@ -890,12 +890,20 @@ public:
const Math::Vector& upVec, float eyeDistance);
//! Loads texture, creating it if not already present
Texture LoadTexture(const std::string& name);
Texture LoadTexture(const std::string& name);
//! Loads texture, creating it with given params if not already present
Texture LoadTexture(const std::string& name, const TextureCreateParams& params);
Texture LoadTexture(const std::string& name, const TextureCreateParams& params);
//! Loads all necessary textures
bool LoadAllTextures();
bool ChangeTextureColor(const std::string& texName,
Color colorRef1, Color colorNew1,
Color colorRef2, Color colorNew2,
float tolerance1, float tolerance2,
Math::Point ts, Math::Point ti,
Math::Point *exclude = nullptr,
float shift = 0.0f, bool hsv = false);
//! Sets texture for given stage; if not present in cache, the texture is loaded
/** If loading fails, returns false. */
bool SetTexture(const std::string& name, int stage = 0);
@ -973,19 +981,19 @@ public:
//@{
//! Ambient color management
void SetAmbientColor(const Color& color, int rank = 0);
Color GetAmbientColor(int rank = 0);
Color GetAmbientColor(int rank = 0);
//@}
//@{
//! Color management under water
void SetWaterAddColor(const Color& color);
Color GetWaterAddColor();
Color GetWaterAddColor();
//@}
//@{
//! Management of the fog color
void SetFogColor(const Color& color, int rank = 0);
Color GetFogColor(int rank = 0);
Color GetFogColor(int rank = 0);
//@}
//@{

View File

@ -4905,7 +4905,7 @@ void CRobotMain::ChangeColor()
exclu[3] = Math::Point(256.0f/256.0f, 256.0f/256.0f); // SatCom screen
exclu[4] = Math::Point(0.0f, 0.0f);
exclu[5] = Math::Point(0.0f, 0.0f); // terminator
// TODO: m_engine->ChangeColor("human.png", colorRef1, colorNew1, colorRef2, colorNew2, 0.30f, 0.01f, ts, ti, exclu);
m_engine->ChangeTextureColor("human.png", colorRef1, colorNew1, colorRef2, colorNew2, 0.30f, 0.01f, ts, ti, exclu);
float tolerance;
@ -4952,7 +4952,7 @@ void CRobotMain::ChangeColor()
exclu[1] = Math::Point(153.0f/256.0f, 79.0f/166.0f); // blue canister
exclu[2] = Math::Point(0.0f, 0.0f);
exclu[3] = Math::Point(0.0f, 0.0f); // terminator
// TODO: m_engine->ChangeColor(name, colorRef1, colorNew1, colorRef2, colorNew2, tolerance, 0.00f, ts, ti, exclu);
m_engine->ChangeTextureColor(name, colorRef1, colorNew1, colorRef2, colorNew2, tolerance, 0.00f, ts, ti, exclu);
colorRef2.r = 0.0f;
colorRef2.g = 0.0f;
@ -4961,19 +4961,19 @@ void CRobotMain::ChangeColor()
colorNew2.g = 0.0f;
colorNew2.b = 0.0f;
// TODO: m_engine->ChangeColor("base1.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
// TODO: m_engine->ChangeColor("convert.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
// TODO: m_engine->ChangeColor("derrick.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
// TODO: m_engine->ChangeColor("factory.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
// TODO: m_engine->ChangeColor("lemt.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
// TODO: m_engine->ChangeColor("roller.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
// TODO: m_engine->ChangeColor("search.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("base1.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("convert.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("derrick.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("factory.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("lemt.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("roller.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
m_engine->ChangeTextureColor("search.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, true);
exclu[0] = Math::Point( 0.0f/256.0f, 160.0f/256.0f);
exclu[1] = Math::Point(256.0f/256.0f, 256.0f/256.0f); // pencils
exclu[2] = Math::Point(0.0f, 0.0f);
exclu[3] = Math::Point(0.0f, 0.0f); // terminator
// TODO: m_engine->ChangeColor("drawer.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, exclu, 0, true);
m_engine->ChangeTextureColor("drawer.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, exclu, 0, true);
exclu[0] = Math::Point(237.0f/256.0f, 176.0f/256.0f);
exclu[1] = Math::Point(256.0f/256.0f, 220.0f/256.0f); // blue canister
@ -4981,26 +4981,26 @@ void CRobotMain::ChangeColor()
exclu[3] = Math::Point(130.0f/256.0f, 214.0f/256.0f); // safe location
exclu[4] = Math::Point(0.0f, 0.0f);
exclu[5] = Math::Point(0.0f, 0.0f); // terminator
// TODO: m_engine->ChangeColor("subm.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, exclu, 0, true);
m_engine->ChangeTextureColor("subm.png", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, exclu, 0, true);
exclu[0] = Math::Point(128.0f/256.0f, 160.0f/256.0f);
exclu[1] = Math::Point(256.0f/256.0f, 256.0f/256.0f); // SatCom
exclu[2] = Math::Point(0.0f, 0.0f);
exclu[3] = Math::Point(0.0f, 0.0f); // terminator
// TODO: m_engine->ChangeColor("ant.png", m_colorRefAlien, m_colorNewAlien, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti, exclu);
// TODO: m_engine->ChangeColor("mother.png", m_colorRefAlien, m_colorNewAlien, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti);
m_engine->ChangeTextureColor("ant.png", m_colorRefAlien, m_colorNewAlien, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti, exclu);
m_engine->ChangeTextureColor("mother.png", m_colorRefAlien, m_colorNewAlien, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti);
// TODO: m_engine->ChangeColor("plant.png", m_colorRefGreen, m_colorNewGreen, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti);
m_engine->ChangeTextureColor("plant.png", m_colorRefGreen, m_colorNewGreen, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti);
// PARTIPLOUF0 and PARTIDROP :
ts = Math::Point(0.500f, 0.500f);
ti = Math::Point(0.875f, 0.750f);
// TODO: m_engine->ChangeColor("effect00.png", m_colorRefWater, m_colorNewWater, colorRef2, colorNew2, 0.20f, -1.0f, ts, ti, 0, m_colorShiftWater, true);
m_engine->ChangeTextureColor("effect00.png", m_colorRefWater, m_colorNewWater, colorRef2, colorNew2, 0.20f, -1.0f, ts, ti, 0, m_colorShiftWater, true);
// PARTIFLIC :
ts = Math::Point(0.00f, 0.75f);
ti = Math::Point(0.25f, 1.00f);
// TODO: m_engine->ChangeColor("effect02.png", m_colorRefWater, m_colorNewWater, colorRef2, colorNew2, 0.20f, -1.0f, ts, ti, 0, m_colorShiftWater, true);
m_engine->ChangeTextureColor("effect02.png", m_colorRefWater, m_colorNewWater, colorRef2, colorNew2, 0.20f, -1.0f, ts, ti, 0, m_colorShiftWater, true);
}
//! Updates the number of unnecessary objects