Extended OBJ loader to parse specular and normal maps

This commit is contained in:
2014-04-23 16:55:51 +02:00
parent 84d6911744
commit 530b16e31b
3 changed files with 242 additions and 29 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ Model::Model(OBJ &obj, ResourceManager* rm)
{
currentMaterial = face.Material;
// Load texture
auto texture = std::shared_ptr<Texture>(rm->Load<Texture>("Texture", currentMaterial->TextureFile));
auto texture = std::shared_ptr<Texture>(rm->Load<Texture>("Texture", currentMaterial->DiffuseTexture.FileName));
// TODO: Load material parameters
// Create new texture group (start index of new group is upcoming index)
TextureGroup texGroup = { texture, index, index };
+172 -19
View File
@@ -126,9 +126,11 @@ void OBJ::ParseMaterial()
std::string currentMaterialName;
MaterialInfo* currentMaterial = nullptr;
unsigned int currentLine = 0;
std::string line;
while (std::getline(file, line))
{
currentLine++;
if (line.length() == 0)
continue;
@@ -140,19 +142,7 @@ void OBJ::ParseMaterial()
// Create a new material definition
if (prefix == "newmtl")
{
MaterialInfo mat =
{
"",
std::make_tuple(0.2f, 0.2f, 0.2f),
std::make_tuple(0.8f, 0.8f, 0.8f),
std::make_tuple(1.0f, 1.0f, 1.0f),
std::make_tuple(1.0f, 1.0f, 1.0f),
1.0f,
1.0f,
0.0f,
0,
};
MaterialInfo mat;
ss >> currentMaterialName;
LOG_INFO("Parsing material %s", currentMaterialName.c_str());
Materials[currentMaterialName] = mat;
@@ -243,14 +233,177 @@ void OBJ::ParseMaterial()
currentMaterial->IlluminationModel = illum;
continue;
}
// Texture file
// TODO:
if (prefix == "map_Ka" || prefix == "map_Kd")
// Diffuse texture
if (prefix == "map_Kd")
{
std::string textureFile;
ss >> textureFile;
currentMaterial->TextureFile = (m_MaterialPath.branch_path() / textureFile).string();
MaterialInfo::ColorMap colorMap;
std::string fileName;
std::string arg;
while (ss >> arg)
{
ParseColorMap(currentLine, ss, prefix, arg, colorMap);
}
// HACK: Should we really have to specify the full path here?
colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string();
currentMaterial->DiffuseTexture = colorMap;
continue;
}
// Specular map
if (prefix == "map_Ks")
{
MaterialInfo::ColorMap colorMap;
std::string fileName;
std::string arg;
while (ss >> arg)
{
ParseColorMap(currentLine, ss, prefix, arg, colorMap);
}
// HACK: Should we really have to specify the full path here?
colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string();
currentMaterial->SpecularMap = colorMap;
continue;
}
// Normal map (bump map)
if (prefix == "bump")
{
MaterialInfo::BumpMap bumpMap;
std::string fileName;
std::string arg;
while (ss >> arg)
{
ParseBumpMap(currentLine, ss, prefix, arg, bumpMap);
}
// HACK: Should we really have to specify the full path here?
bumpMap.FileName = (m_MaterialPath.branch_path() / bumpMap.FileName).string();
currentMaterial->NormalMap = bumpMap;
continue;
}
}
}
void OBJ::ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap)
{
if (arg == "-blendu")
{
std::string val;
ss >> val;
if (val == "off")
textureMap.blendu = false;
else if (val == "on")
textureMap.blendu = true;
else
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
}
else if (arg == "-blendv")
{
std::string val;
ss >> val;
if (val == "off")
textureMap.blendv = false;
else if (val == "on")
textureMap.blendv = true;
else
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
}
else if (arg == "-clamp")
{
std::string val;
ss >> val;
if (val == "off")
textureMap.clamp = false;
else if (val == "on")
textureMap.clamp = true;
else
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
}
else if (arg == "-o")
{
float u, v, w;
if (ss >> u >> v >> w)
{
textureMap.o = std::make_tuple(u, v, w);
}
else
{
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
}
}
else if (arg == "-s")
{
float u, v, w;
if (ss >> u >> v >> w)
{
textureMap.s = std::make_tuple(u, v, w);
}
else
{
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
}
}
// Assume unrecognized options is part of the file name
else
{
if (!textureMap.FileName.empty())
textureMap.FileName += " ";
textureMap.FileName += arg;
}
}
void OBJ::ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &colorMap)
{
if (arg == "-cc")
{
if (prefix != "map_Kd" || prefix != "map_Ks")
{
LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line);
return;
}
std::string val;
if (ss >> val)
{
if (val == "off")
colorMap.cc = false;
else if (val == "on")
colorMap.cc = true;
else
LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line);
}
else
{
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
}
}
else
{
ParseTextureMap(line, ss, prefix, arg, colorMap);
}
}
void OBJ::ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &bumpMap)
{
if (arg == "-bm")
{
if (prefix != "bump")
{
LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line);
return;
}
float val;
if (ss >> val)
bumpMap.bm = val;
else
LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line);
}
else
{
ParseTextureMap(line, ss, prefix, arg, bumpMap);
}
}
+69 -9
View File
@@ -10,21 +10,78 @@
#include <map>
#include <boost/filesystem/path.hpp>
#include <boost/program_options.hpp>
class OBJ
{
public:
struct MaterialInfo
{
std::string TextureFile;
std::tuple<float, float, float> AmbientColor;
std::tuple<float, float, float> DiffuseColor;
std::tuple<float, float, float> SpecularColor;
std::tuple<float, float, float> TransmissionFilter;
float OpticalDensity;
float Alpha;
float Shininess;
int IlluminationModel;
struct TextureMap
{
TextureMap()
: blendu(true)
, blendv(true)
, clamp(false)
, o(std::make_tuple(0.f, 0.f, 0.f))
, s(std::make_tuple(1.f, 1.f, 1.f)) { }
std::string FileName;
// http://paulbourke.net/dataformats/mtl/
// "These options are described in detail in 'Options for texture map statements' on page 5-18."
// Horizontal texture blending
bool blendu; // = true
// Vertical texture blending
bool blendv; // = true
// Clamping
bool clamp; // = false
// Offset
std::tuple<float, float, float> o; // = (0, 0, 0)
// Scale
std::tuple<float, float, float> s; // = (1, 1, 1)
};
struct ColorMap : public TextureMap
{
ColorMap()
: cc(false) { }
// Color correction
bool cc; // = false
};
struct BumpMap : public TextureMap
{
BumpMap()
: bm(1.f) { }
// Bump multiplier
float bm; // = 1?
};
MaterialInfo()
: AmbientColor(std::make_tuple(0.2f, 0.2f, 0.2f))
, DiffuseColor(std::make_tuple(0.8f, 0.8f, 0.8f))
, SpecularColor(std::make_tuple(1.0f, 1.0f, 1.0f))
, TransmissionFilter(std::make_tuple(1.0f, 1.0f, 1.0f))
, OpticalDensity(1.0f)
, Alpha(1.0f)
, Shininess(0.0f)
, IlluminationModel(0) { }
ColorMap DiffuseTexture;
ColorMap SpecularMap;
BumpMap NormalMap;
std::tuple<float, float, float> AmbientColor; // = (0.2, 0.2, 0.2)
std::tuple<float, float, float> DiffuseColor; // = (0.8, 0.8, 0.8)
std::tuple<float, float, float> SpecularColor; // = (1, 1, 1)
std::tuple<float, float, float> TransmissionFilter; // = (1, 1, 1)
float OpticalDensity; // = 1
float Alpha; // = 1
float Shininess; // = 0
int IlluminationModel; // = 0
};
struct FaceDefinition
@@ -59,6 +116,9 @@ private:
MaterialInfo* m_CurrentMaterial;
void ParseMaterial();
void ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap);
void ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &textureMap);
void ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &textureMap);
};
#endif // OBJ_h__