我正在尝试为我的游戏引擎创建一个模型加载器,它接受一个.obj目标文件(来自blender)并将其转换为带索引和顶点的模型,但是uv坐标似乎已经移位且非常不正确。
以下是模型加载器的代码:
bool RawModel::LoadModel(std::string fileName)
{
m_name = fileName;
int pos = m_name.find_last_of("\\");
if (pos >= 0)
{
m_name = m_name.substr(pos + 1, m_name.length());
}
//Load vertices:
m_vertices.clear();
m_indices.clear();
std::ifstream objFile(fileName);
if (!objFile.is_open())
{
std::cout << "Could not open file: " << fileName << std::endl;
return false;
}
std::string currentLine;
std::vector<Vector3> vertices;
std::vector<Vector2> uvs;
std::vector<Vector3> normals;
while (objFile.good())
{
std::getline(objFile, currentLine);
if (currentLine.find("v ") != std::string::npos) //Vertex
{
std::stringstream streamedLine(currentLine);
float x, y, z;
std::string temps;
streamedLine >> temps;
streamedLine >> x;
streamedLine >> y;
streamedLine >> z;
vertices.push_back(Vector3(x, y, z));
}
else if (currentLine.find("vt ") != std::string::npos) //Uv
{
std::stringstream streamedLine(currentLine);
float x, y;
std::string temps;
streamedLine >> temps;
streamedLine >> x;
streamedLine >> y;
uvs.push_back(Vector2(x, 1-y)); //-y because top is 0y not 1y as in normal coordinate space
}
else if (currentLine.find("vn ") != std::string::npos) //Normal
{
std::stringstream streamedLine(currentLine);
float x, y, z;
std::string temps;
streamedLine >> temps;
streamedLine >> x;
streamedLine >> y;
streamedLine >> z;
vertices.push_back(Vector3(x, y, z));
}
else if (currentLine.find("f ") != std::string::npos)
{
m_vertices.resize(vertices.size());
std::stringstream streamedLine(currentLine);
std::string segment;
streamedLine >> segment;
std::vector<std::string> indices;
indices.reserve(3);
//getting the triangulated face to a array
while (streamedLine >> segment)
indices.push_back(segment);
for (int i = 0; i < indices.size(); i++) //Loop all indices in the face
{
std::stringstream streamedIndex(indices[i]);
std::vector<int> vertex;//0 = vertexPos, 1 = uv, 2 = normal
indices.reserve(3);
while (std::getline(streamedIndex, segment, '/')) //x3
{
vertex.push_back(stoi(segment)-1);
}
m_vertices[vertex[0]] = VertexType(vertices[vertex[0]], uvs[vertex[1]]);
m_indices.emplace_back(vertex[0]);
}
}
}
return true;
}
VertexType
是一个结构,它是顶点的结构。顶点是建立起来的,定义如下:
struct VertexType
{
D3DXVECTOR3 position;
D3DXVECTOR2 uv;
D3DXVECTOR3 normal;
VertexType() : position(0, 0, 0), uv(0, 0) {};
VertexType(D3DXVECTOR3 position, D3DXVECTOR2 uv, D3DXVECTOR3 normal) :position(position), uv(uv), normal(normal) {};
VertexType(Vector3 position, Vector2 uv) :position(position.D3DXVECTOR()), uv(uv.D3DXVECTOR()) {};
};
这是正常工作时的样子
这就是它在我的游戏引擎中的样子:
我怀疑模型的错误,因为它在统一和混合器中使用相同的纹理(绿色和红色在uv坐标之外,根据uv布局,透明部分通常应该是绿色和红色的轻松。)(纹理底部为红色,顶部为绿色)
这是两种情况下使用的纹理。
答案 0 :(得分:0)
加载OBJ文件后,我记得这个问题。我在C#中的修复,我相信你可以在这里申请。
vp.SetTextureUV(result.Textures[TextureIndex].X, -result.Textures[TextureIndex].Y);
当您设置UV的V分量时,我不得不在格式中出于某种原因否定该值,以使其与我的纹理一起使用。我希望这也能解决你的问题。从截图中,我认为它会。
您可以在Y轴上翻转纹理,这也应该可以解决问题。